初始化没有键的DbSet时出错:无法跟踪类型为'MyEntity'的实例,因为它没有主键 [英] Error on initialize a DbSet without key: Unable to track an instance of type 'MyEntity' because it does not have a primary key
问题描述
我有一个 DbContext
,其中有一个 Dbset
而没有密钥.它可以在仅查询表的应用程序中工作.
I have a DbContext
which has a Dbset
without Key. It works in the application, which only queries the table.
public class MyDbContext : DbContext, IMyDbContext
{
public MyDbContext(DbContextOptions<MyDbContext> options) : base(options) { }
public DbSet<MyEntity> MyEntities { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MyEntity>().HasNoKey(); // No key
modelBuilder.ApplyConfigurationsFromAssembly(typeof(MyDbContext).Assembly);
}
}
我在测试项目(xUnit)中创建以下测试设置类:
I create the following test setup classes in the test project (xUnit):
public static class MyDbContextFactory
{
internal static MyDbContext Create()
{
var options = new DbContextOptionsBuilder<MyDbContext>()
.UseInMemoryDatabase(Guid.NewGuid().ToString())
.Options;
var context = new MyDbContext(options);
context.Database.EnsureCreated();
context.MyEnities.AddRange(new[] // This line got the error!!!
{
new MyEntity { Time = DateTime.Now, Instrument = "R1" },
new MyEntity { Time = DateTime.Now, Instrument = "R2" },
new MyEntity { Time = DateTime.Now, Instrument = "R3" },
});
context.SaveChanges();
return context;
}
}
public class QueryTestFixture : IDisposable
{
public MyDbContext MyDbContext { get; }
public IMapper Mapper { get; }
public QueryTestFixture()
{
MyDbContext = MyDbContextFactory.Create();
var configurationProvider = new MapperConfiguration(cfg =>
{
cfg.AddProfile<MappingProfile>();
});
Mapper = configurationProvider.CreateMapper();
}
public void Dispose()
{
// ... omitted ...
}
}
[CollectionDefinition("QueryTests")]
public class QueryCollection : ICollectionFixture<QueryTestFixture> { }
这是测试代码.
[Collection("QueryTests")]
public class MyTest
{
private readonly MyDbContext _context;
private readonly IMapper _mapper;
public MyTest(QueryTestFixture fixture)
{
_context = fixture.MyDbContext;
_mapper = fixture.Mapper;
}
}
但是,在实际运行测试之前,运行任何测试方法都会出现以下错误.错误发生在上面的 context.MyEnities.AddRange(....
.
However, running any test method will get the following error before the tests are actually run. The error occurred on the line context.MyEnities.AddRange(....
above.
Message:
System.AggregateException : One or more errors occurred. (Unable to track an instance of type 'MyEntity' because it does not have a primary key. Only entity types with primary keys may be tracked.) (The following constructor parameters did not have matching fixture data: QueryTestFixture fixture)
---- System.InvalidOperationException : Unable to track an instance of type 'MyEntity' because it does not have a primary key. Only entity types with primary keys may be tracked.
---- The following constructor parameters did not have matching fixture data: QueryTestFixture fixture
Stack Trace:
----- Inner Stack Trace #1 (System.InvalidOperationException) -----
StateManager.GetOrCreateEntry(Object entity)
DbContext.SetEntityStates(IEnumerable`1 entities, EntityState entityState)
DbContext.AddRange(IEnumerable`1 entities)
DbContext.AddRange(Object[] entities)
InternalDbSet`1.AddRange(TEntity[] entities)
MyDbContextFactory.Create() line 20
QueryTestFixture.ctor() line 16
----- Inner Stack Trace #2 (Xunit.Sdk.TestClassException) -----
推荐答案
Until now this is an open issue on Entity Framework: https://github.com/aspnet/EntityFramework.Docs/issues/898
您不能在没有键的DbQuery或DbSet上添加新实体.我建议您跟踪此问题,现在模拟您的上下文或使用实体框架Core Mock 来实现这一目标.
You can not add new entities on a DbQuery or an DbSet with no key. I suggest you to keep track on this issue and for now mock your Context or to use Entity Framework Core Mock to accomplish that.
这篇关于初始化没有键的DbSet时出错:无法跟踪类型为'MyEntity'的实例,因为它没有主键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!