最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

entity framework core - Cannot create a DbSet for 'Product' because this type is not included in the model for t

programmeradmin2浏览0评论

I'm trying to unit test the derived class of a dbContext. I keep getting the error message

[Fact]
public void GetAssync_Method_Called()
{
   var options = new DbContextOptionsBuilder<CoreDbContext>()
       //.UseModel()       USE MODEL
       .UseInMemoryDatabase(databaseName: "test")
       .Options;

    using (var context = new CoreDbContext(options))
    {

       context.Set<Product>(); //THIS IS THE WAY TO ADD AN ENTITY IN THE CONTEXT...????

       Expression<Func<Product, bool>> filter = x => !x.IsDeleted == 1;
       var result = GetAllAsNoTrackin(filter);

       Assert.Equal(1, result.Count());
    }
}

Below are the CoreDbContext and the method I'm testing.

public class CoreDbContext : DbContext
{
   public CoreDbContext(DbContextOptions<CoreDbContext> options) : base(options)
   {
   }

   public IQueryable<Product> GetAllAsNoTrackin(Expression<Func<Product, bool>> filter)
   {
       var dbSet = Set<Product>().AsNoTracking(); //GETTING ERROR HERE...

       //more code...
   }
 }

I keep getting the same error:

Cannot create a DbSet for 'Product' because this type is not included in the model for the context

After googling, it looks like DbContextOptionsBuilder has a method called UseModel(IModel model) that can be called instead of the OnModelCreating(ModelBuilder builder).

Unfortunately, I didn't see anywhere any code on how to use it. Also, adding a new entity is happening after the context has been create, while UseModel() is an extension method of the options to be passed to the DbContext.

Thanks for helping

I'm trying to unit test the derived class of a dbContext. I keep getting the error message

[Fact]
public void GetAssync_Method_Called()
{
   var options = new DbContextOptionsBuilder<CoreDbContext>()
       //.UseModel()       USE MODEL
       .UseInMemoryDatabase(databaseName: "test")
       .Options;

    using (var context = new CoreDbContext(options))
    {

       context.Set<Product>(); //THIS IS THE WAY TO ADD AN ENTITY IN THE CONTEXT...????

       Expression<Func<Product, bool>> filter = x => !x.IsDeleted == 1;
       var result = GetAllAsNoTrackin(filter);

       Assert.Equal(1, result.Count());
    }
}

Below are the CoreDbContext and the method I'm testing.

public class CoreDbContext : DbContext
{
   public CoreDbContext(DbContextOptions<CoreDbContext> options) : base(options)
   {
   }

   public IQueryable<Product> GetAllAsNoTrackin(Expression<Func<Product, bool>> filter)
   {
       var dbSet = Set<Product>().AsNoTracking(); //GETTING ERROR HERE...

       //more code...
   }
 }

I keep getting the same error:

Cannot create a DbSet for 'Product' because this type is not included in the model for the context

After googling, it looks like DbContextOptionsBuilder has a method called UseModel(IModel model) that can be called instead of the OnModelCreating(ModelBuilder builder).

Unfortunately, I didn't see anywhere any code on how to use it. Also, adding a new entity is happening after the context has been create, while UseModel() is an extension method of the options to be passed to the DbContext.

Thanks for helping

Share Improve this question edited Nov 15, 2024 at 21:41 marc_s 757k184 gold badges1.4k silver badges1.5k bronze badges asked Nov 15, 2024 at 21:23 Richard77Richard77 21.7k52 gold badges165 silver badges273 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

A DbContext needs to know about entities, it doesn't discover and assume every class you define in a project is an entity. There are a few ways this can be done via convention and/or by explicit configuration.

The most common way a DbContext knows about entities is through declared DbSets:

public class CoreDbContext : DbContext
{
    public DbSet<Product> Products { get; set; } 
}

Here the DbContext initialization will be aware of a Product entity and use conventions to marry it, and its public properties, including navigation property entity types, to tables.

Where you do not have a DbSet or relation to an entity with a DbSet, or convention cannot be followed to map it correctly, you need explicit configuration. The two common approaches are through OnModelCreating or using an IEntityTypeConfiguration

In OnModelCreating() you would declare entities:

modelBuilder.Entity<Product>();

That tells the DbContext at the minimum to expect a Product entity. Everything will be resolved by convention or attributes declared in the entity class.

Using IEntityTypeConfiguration<TEntity> involves creating classes that implement this interface to provide the configuration for that entity model. For larger projects this helps anize entity configuration rather than having a huge OnModelCreating() full of configurations for all entities in the system. Once these are defined they can be registered with the model builder using modelBuilder.ApplyConfigurationsFromAssembly(GetType().Assembly); within the OnModelCreating. This assumes the entities are declared in the same assembly as the DbContext, otherwise you can pass whatever assembly reference(s) to locate the IEntityTypeConfiguration implementations for each entity. A DbContext can access configured entities via Set<TEntity> but it's generally simpler to declare and access these entities through DbSet<TEnitity> properties in the DbContext.

Pretty much everything to do with accessing and configuring entities and DbContexts is covered in depth with examples in Microsoft's documentation: https://learn.microsoft/en-us/ef/core/

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论