Как заполнить игнорируемое поле внутри OnModelCreating?

Я использую один и тот же объект в двух DbContexts.

public class ActualDbContext : DbContext
{
    public DbSet<Doc> Docs { get; set; }
}

public class ArchivedDbContext : DbContext
{
    public DbSet<Doc> Docs { get; set; }
}

public class Doc
{
    ...
}

Как я могу добавить игнорируемое поле в этот объект, но заполнить его из DbContext?

public class Doc
{
    ...
    public bool IsArchived {get;set;}
}

public class ActualDbContext : DbContext
{
    protected override void OnModelCreating(ModelBuilder builder)
    {

        builder.Entity<Doc>(entity =>
        {
            entity
                .Ignore(x => x.IsArchived)
                .WithValue(x => false);        // ??
        };
    }
}


public class ArchivedDbContext : DbContext
{
    protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.Entity<Doc>(entity =>
        {
            entity
                .Ignore(x => x.IsArchived)
                .WithValue(x => true);        // ??
        };
    }
}

При чтении данных из базы это свойство необходимо заполнять. В программном коде хочется избежать дублирования кода. Мне нужно работать с этими сущностями таким же образом. За исключением этого свойства. Как я могу это сделать ?

@ali, ты имеешь в виду что-то подобное?

class MyRepo: IRepo
{
    private bool _isArchived;

    public MyRepo (MyContext context, bool isArchived)
    {
        _context = context;
       _isArchived = isArchived;
    }

    public IQueryable<Doc> GetData (...)
    {
        return _mainDbContext.Docs.Where(....)
            .Select (x=> new Doc 
            {
                Id = x.Id,
                IsArchived = _isArchived 
            });
    }

}

Мне не очень нравится это решение.


person Michael Zagorski    schedule 30.03.2020    source источник


Ответы (2)


Итак, вы можете сделать это, переопределив onmodelcreating его базовый класс.

public class ActualDbContext : DbContext
{
    public ActualDbContext (DbContextOptions<ActualDbContext > options) : base(options)
    {
    }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Doc>().Ignore(t => t.IsArchived);
        base.OnModelCreating(modelBuilder);
    }
    public DbSet<Doc> Docs { get; set; }
}

Проверьте этот ответ для получения дополнительных объяснений => a-class-property-in-entity

Добрый день ????

person Pritom    schedule 30.03.2020
comment
Мой вопрос о другом. Не о том, как настроить игнорируемое поле. Речь идет о том, как заполнить его в контексте. - person Michael Zagorski; 30.03.2020
comment
Я смущен вашим вопросом. почему вы хотите игнорировать свойство, если хотите заполнить его желаемым значением? Если вы игнорируете это, имеет ли значение, чем вы заполняете? Это не будет учитываться, когда вы получите свое значение из базы данных. Правильно ? - person Pritom; 30.03.2020
comment
В программном коде архивные и текущие документы я обрабатываю одинаково, за исключением пары строчек отличия. Мне нужно показать, что запись архивная или актуальная. - person Michael Zagorski; 30.03.2020
comment
Итак, вы хотите, чтобы статус IsArchived для всех ваших документов был истинным? Помогите мне понять, что вы хотите показать и каков ваш текущий статус БД. - person Pritom; 30.03.2020

На базе архитектуры ef core такое сделать невозможно. Я предлагаю использовать шаблон репозитория и установить значение по умолчанию для ваших сущностей при извлечении данных.

Class MyRepo: IRepo
{
    private ActualDbContext _mainDbContext;
    private ArchivedDbContext _archivedContext;
    public MyRepo (ActualDbContext context , ArchivedDbContext archivedContext)
    {
        _mainDbContext = context;
        _archivedContext = archivedContext;
    }
    public IQueryable<Doc> GetMainData (...)
    {
        return _mainDbContext.Docs.Where(....)
            .Select (x=> new Doc 
            {
                Id = x.Id,
                IsArchived = false
            });
    }

    public IQueryable<Doc> GetArchivedData (...)
    {
        return _archivedContext.Docs.Where(....)
            .Select (x=> new Doc 
            {
                Id = x.Id,
                IsArchived = true
            });
    }

}
person Ali Kamali    schedule 30.03.2020
comment
вы можете использовать шаблон репозитория, подобный этому. это делает ваш код чище. - person Ali Kamali; 31.03.2020