首页 > 解决方案 > EF Core - 动态使用 DbSet 和泛型

问题描述

我的 DI 中附加了一个接口

builder.RegisterType<TaskTempo>().As<ITaskTempo>();

这样做是因为ITaskTempo它是动态的,并且可能是多个对象之一,但共享相同的界面。

无论如何,我有手动DbContext映射实体的地方DbSet

// DI register
builder.RegisterType<MapperFor890>().As<IEntityMapper>();

// ...
// DbContext

public partial class MyDBContext : DbContext
{
    private readonly IEntityMapper _entityMapper;

    // Please not that I do not want to manually add all of diff implementations of ITaskTempo here
    // public virtual DbSet<TaskTempo1> TaskTempo { get; set; }


    public MyDBContext(DbContextOptions<MyDBContext> options, IEntityMapper mapper)
        : base(options)
    {
        _entityMapper = mapper;
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Map Entities
        _entityMapper.Map(modelBuilder, this);
    }
}

// ...
// EntityMapper
public class MapperFor890 : IEntityMapper
{
    public void Map(ModelBuilder modelBuilder, DbContext context)
    {
        modelBuilder.Entity<TaskTempo1>(entity => 
        {
            // Map here the properties
        });
    }
}

然后,我可以从以下位置获取数据EfRepository

// Global Repository
public class EfRepository<TEntity> : IRepository<TEntity> where TEntity : class
{
    protected readonly DbContext Context;
    protected readonly ILogger<EfRepository<TEntity>> Logger;

    public EfRepository(DbContext context,
        ILogger<EfRepository<TEntity>> logger)
    {
        Context = context;
        Logger = logger;
    }

    public virtual IQueryable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
    {
        Logger.LogDebug($"Finding '{typeof(TEntity).Name}' with predicate");
        return Context.Set<TEntity>().Where(predicate);
    }
}

// TaskTempo Repository
public class TaskTempoRepository<TTaskTempo> : EfRepository<TTaskTempo>, ITaskScanRepository<TTaskTempo> where TTaskTempo : class, ITaskTempo
{
    public MyDBContext DbContext => Context as MyDBContext;

    public TaskScanRepository(MyDBContext context, ILogger<TaskScanRepository<TTaskTempo>> logger) : base(context,logger)
    {
    }
}

// DI injection
builder.RegisterType<TaskTempo1>().As<ITaskTempo>();
builder.RegisterType<TaskTempoRepository<ITaskTempo>>().As<ITasTempoRepository<ITaskTempo>>();

一旦我取

_taskTempoRepository.Find(t => t.Id = 3);

我收到以下错误:

无法为“ITaskTempo”创建 DbSet,因为此类型未包含在上下文模型中

标签: c#entity-framework-coreautofac

解决方案


推荐阅读