Как заполнить пропущенное поле внутри OnModelCreating? - PullRequest
1 голос
/ 30 марта 2020

Я использую одну и ту же сущность в двух 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 
            });
    }

}

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

Ответы [ 2 ]

0 голосов
/ 30 марта 2020

Итак, вы можете сделать это, переопределив 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; }
}

Проверьте этот ответ для более подробного объяснения => ignoring-a-class-property-in-entity

Добрый день ?

0 голосов
/ 30 марта 2020

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

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
            });
    }

}
...