【问题标题】:Cannot create a DbSet for 'Model' because this type is not included in the model for the context无法为“模型”创建 DbSet,因为此类型未包含在上下文的模型中
【发布时间】:2018-03-22 09:48:20
【问题描述】:

我做一个泛型并使用 DI

所以我创建了一个空类

public class DBRepo
{ 
}

和我的模型类继承类 DBRepo

public partial class UserAccount : DBRepo
{
   public int Id { get; set; }
   public string Account { get; set; }
   public string Pwd { get; set; }
}

那么这是一个执行 CRUD 的接口

    public interface IDBAction<TEntity> where TEntity : class,new()
    {   
      void UpdateData(TEntity _entity);
      void GetAllData(TEntity _entity);
    }
public class DBService<TEntity> : IDBAction<TEntity> where TEntity : class,new()
{
    private readonly CoreContext _db;
    public DBService(CoreContext _db)
    {
        this._db = _db;
    }
    public void UpdateData(TEntity _entity)
    {
        this._db.Set<TEntity>().UpdateRange(_entity);
        this._db.SaveChanges();
    }
    public void GetAllData(TEntity _entity)
    {
        var x = this._db.Set<TEntity>().Select(o => o).ToList();
    }
}

我在构造函数中的依赖注入服务提供者

this.DBProvider = new ServiceCollection()
    .AddScoped<IDBAction<DBRepo>, DBService<DBRepo>>()
    .AddScoped<DBContext>()
    .AddDbContext<CoreContext>(options => options.UseSqlServer(ConnectionString))
    .BuildServiceProvider();

我获得服务的最后一步

DBProvider.GetService<IDBAction<DBRepo>>().GetAllData(new UserAccount());

我会收到与标题相同的错误消息

或者我改成

DBProvider.GetService<IDBAction<UserAccount>>().GetAllData(new UserAccount());

我会收到其他消息

对象引用未设置为对象的实例。'

但是 void UpdateData() 可以工作, 那么如何解决 GetAllData() 问题呢?

【问题讨论】:

    标签: asp.net-core dependency-injection


    【解决方案1】:

    这个错误仅仅是因为你在这里使用的类UserAccount 显然没有被添加到你的上下文中,CoreContext。那里应该有一个属性,例如:

    public DbSet<UserAccount> UserAccounts { get; set; }
    

    无论您最终是否使用通用的Set&lt;T&gt; 访问器,您仍然必须为上下文中的实体定义一个DbSet

    也就是说,您绝对不应该在您的存储库中创建自己的服务集合。使用 Startup.cs 中的主要服务集合注册您的上下文和您的 repo,然后只需将您的 repo 注入您需要的地方。只要您有一个构造函数来获取您的上下文(您似乎是这样),DI 框架就会使用您的上下文来实例化它。

    说,你应该完全放弃 repo。它仍然需要对实体框架的依赖,并且除了代理实体框架方法之外什么都不做。这只是您必须维护和测试的额外内容,没有额外的好处。

    【讨论】:

    • 那么如何在 Startup.cs 中做你能告诉我一个简单的示例吗?
    • 这很烦人。那么,必须为他想要从数据库结果映射的每个 POCO 对象添加一个新属性吗?我使用 SP 和 _dbContext.Set&lt;MyPOCO&gt;().FromSql("....") 来获取结果,这个解决方案将用属性填充我的数据库上下文!我发现另一篇文章说您可以从 Startup.cs EF 设置中执行相同操作:uilder.Entity&lt;MyPOCO&gt;().HasKey(p =&gt; new { p.Prop1, p.Prop2 });。但这对于简单的反序列化操作来说似乎太多了。没有其他选择吗?
    • 有多烦人?事情就是这样运作的。 DbContext 是工作单元,因此,它需要添加存储库(即每个 DbSet)。更抽象地说,除非您明确地告诉它,否则上下文应该如何了解您的实体。归根结底,实体只是 POCO,所以即使 EF 想在这里帮助你,它也只能添加所有存在的类,这显然是不可取的。
    • 另外,您没有使用 EF。如果您要处理的只是存储过程,那么像 Dapper 这样的微型 ORM 可能更合适。
    猜你喜欢
    • 2019-08-16
    • 2019-07-13
    • 2019-07-10
    • 1970-01-01
    • 2018-10-20
    • 1970-01-01
    • 2022-01-08
    • 2020-03-09
    • 2019-01-04
    相关资源
    最近更新 更多