efcore
efcore copied to clipboard
Cannot create a DbSet because this type is not included in the model for the context
EF Core version: 8.0.6 Database provider: Postgres Target framework: .NET 8.0 Operating system: Linux Debian 12 IDE: JetBrains Rider
=== Description
Updating EF Core version from 7.0.20 to 8.0.6 I encountered the error where DbSet<T>.Update() stopped working for multi level include.
It drops the error:
Cannot create a DbSet for 'IIncludableQueryable<OrderItemEntity, ProductPriceEntity>' because this type is not included in the model for the context.
System.InvalidOperationException: Cannot create a DbSet for 'IIncludableQueryable<OrderItemEntity, ProductPriceEntity>' because this type is not included in the model for the context.
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_EntityType()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.EntryWithoutDetectChanges(TEntity entity)
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.Update(TEntity entity)
at LSCore.Domain.Managers.LSCoreManagerBase`1.Update[TEntity](TEntity entity)
=== Code and configuration used
Part of the code that drops the error:
var orderItems = dbContext.Set<OrderItemEntity>().AsQueryable()
.Where(x =>
x.IsActive &&
x.OrderId == request!.Id)
.Include(x => x.Product)
.ThenInclude(x => x.Price);
if (!orderItems.Any())
return;
if(request.UserId == null)
CalculateAndApplyOneTimePrices();
else
CalculateAndApplyUserPrices();
dbContext.Set<OrderItemEntity>().Update(orderItems);
dbContext.SaveChanges(); // This part trows the error
using TD.Web.Common.Repository.DbMappings;
using TD.Web.Common.Contracts.Entities;
using Microsoft.EntityFrameworkCore;
using LSCore.Repository;
namespace TD.Web.Common.Repository;
public class WebDbContext(DbContextOptions<WebDbContext> options) : LSCoreDbContext<WebDbContext>(options)
{
public DbSet<UnitEntity> Units { get; set; }
public DbSet<UserEntity> Users { get; set; }
public DbSet<CityEntity> Cities { get; set; }
public DbSet<OrderEntity> Orders { get; set; }
public DbSet<StoreEntity> Stores { get; set; }
public DbSet<ProductEntity> Products { get; set; }
public DbSet<SettingEntity> Settings { get; set; }
public DbSet<OrderItemEntity> OrderItems { get; set; }
public DbSet<ProfessionEntity> Professions { get; set; }
public DbSet<GlobalAlertEntity> GlobalAlerts { get; set; }
public DbSet<PaymentTypeEntity> PaymentTypes { get; set; }
public DbSet<ProductGroupEntity> ProductGroups { get; set; }
public DbSet<ProductPriceEntity> ProductPrices { get; set; }
public DbSet<StatisticsItemEntity> StatisticsItems { get; set; }
public DbSet<ProductPriceGroupEntity> ProductPriceGroups { get; set; }
public DbSet<ProductPriceGroupLevelEntity> ProductPriceGroupLevel { get; set; }
public DbSet<OrderOneTimeInformationEntity> OrderOneTimeInformation { get; set; }
public DbSet<KomercijalnoWebProductLinkEntity> KomercijalnoWebProductLinks { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<UnitEntity>().AddMap(new UnitEntityMap());
modelBuilder.Entity<CityEntity>().AddMap(new CityEntityMap());
modelBuilder.Entity<UserEntity>().AddMap(new UserEntityMap());
modelBuilder.Entity<OrderEntity>().AddMap(new OrderEntityMap());
modelBuilder.Entity<StoreEntity>().AddMap(new StoreEntityMap());
modelBuilder.Entity<SettingEntity>().AddMap(new SettingEntityMap());
modelBuilder.Entity<ProductEntity>().AddMap(new ProductEntityMap());
modelBuilder.Entity<OrderItemEntity>().AddMap(new OrderItemEntityMap());
modelBuilder.Entity<ProfessionEntity>().AddMap(new ProfessionEntityMap());
modelBuilder.Entity<GlobalAlertEntity>().AddMap(new GlobalAlertEntityMap());
modelBuilder.Entity<PaymentTypeEntity>().AddMap(new PaymentTypeEntityMap());
modelBuilder.Entity<ProductGroupEntity>().AddMap(new ProductGroupEntityMap());
modelBuilder.Entity<ProductPriceEntity>().AddMap(new ProductPriceEntityMap());
modelBuilder.Entity<StatisticsItemEntity>().AddMap(new StatisticsItemEntityMap());
modelBuilder.Entity<ProductPriceGroupEntity>().AddMap(new ProductPriceGroupEntityMap());
modelBuilder.Entity<ProductPriceGroupLevelEntity>().AddMap(new ProductPriceGroupLevelEntityMap());
modelBuilder.Entity<OrderOneTimeInformationEntity>().AddMap(new OrderOneTimeInformationEntityMap());
modelBuilder.Entity<KomercijalnoWebProductLinkEntity>().AddMap(new KomercijalnoWebProductLinkEntityMap());
}
}
// LSCoreDbContext
namespace LSCore.Repository
{
public abstract class LSCoreDbContext<TContext> : DbContext, ILSCoreDbContext where TContext : DbContext
{
protected LSCoreDbContext(DbContextOptions<TContext> options)
: base((DbContextOptions) options)
{
}
}
}
And the mapper:
public class OrderItemEntityMap : LSCoreEntityMap<OrderItemEntity>
{
public override Action<EntityTypeBuilder<OrderItemEntity>> Mapper { get; } = entityTypeBuilder =>
{
entityTypeBuilder
.HasOne(x => x.Order)
.WithMany(x => x.Items)
.HasForeignKey(x => x.OrderId);
entityTypeBuilder
.HasOne(x => x.Product)
.WithMany()
.HasForeignKey(x => x.ProductId);
entityTypeBuilder
.Property(x => x.Price)
.IsRequired();
entityTypeBuilder
.Property(x => x.Quantity)
.IsRequired();
entityTypeBuilder
.Property(x => x.PriceWithoutDiscount)
.IsRequired();
};
}
// LSCore entity map
namespace LSCore.Repository
{
public abstract class LSCoreEntityMap<TEntity> : ILSCoreEntityMap<TEntity> where TEntity : class, ILSCoreEntity
{
private bool _suppressDefaultMapping { get; set; }
public abstract Action<EntityTypeBuilder<TEntity>> Mapper { get; }
protected LSCoreEntityMap()
{
}
protected LSCoreEntityMap(bool suppressDefaultMapping)
{
this._suppressDefaultMapping = suppressDefaultMapping;
}
public EntityTypeBuilder<TEntity> Map(EntityTypeBuilder<TEntity> entityTypeBuilder)
{
if (!this._suppressDefaultMapping)
this.MapDefaultFields(entityTypeBuilder);
this.Mapper(entityTypeBuilder);
return entityTypeBuilder;
}
private void MapDefaultFields(EntityTypeBuilder<TEntity> entityTypeBuilder)
{
entityTypeBuilder.HasKey((Expression<Func<TEntity, object>>) (x => (object) x.Id));
entityTypeBuilder.Property<DateTime>((Expression<Func<TEntity, DateTime>>) (x => x.CreatedAt)).IsRequired(true);
entityTypeBuilder.Property<bool>((Expression<Func<TEntity, bool>>) (x => x.IsActive)).HasDefaultValue<bool>((object) true).IsRequired(true);
entityTypeBuilder.Property<DateTime?>((Expression<Func<TEntity, DateTime?>>) (x => x.UpdatedAt)).IsRequired(false);
entityTypeBuilder.Property<long?>((Expression<Func<TEntity, long?>>) (x => x.UpdatedBy)).IsRequired(false);
foreach (PropertyInfo property in typeof (TEntity).GetProperties())
{
if (property.PropertyType == typeof (DateTime))
entityTypeBuilder.Property(property.PropertyType, property.Name).HasColumnType("timestamp");
}
}
}
}
=== Debugging info
Strange thing I encountered while debugging is that select does enumerate everything as it should (indicating that dbSet is there and mapping works) but only save changes makes mistake.