我正在为一个C#>Sql Server应用程序编写单元测试。MS建议在不使用生产数据库进行测试时使用SQLite(https://learn.microsoft.com/en-us/ef/core/testing/testing-without-the-database#inmemory-provider)。我有SQLite设置,我试图用测试数据填充数据库。我将一个生产数据样本导出为JSON格式,并将其与测试项目一起保存,这样我就可以相当容易地更新测试数据。设置SQLite上下文的代码我取自MS文章
除了这个块,没有行号可以引用
var memoryData = new ReqestDataInMemory();
var data = memoryData.AllRepositoryRequests();
获取json并将复杂对象结构作为IEnumberable返回。然后我尝试将其保存到db上下文。
public class TestDbContext
{
public SqliteConnection _connection {get; set;}
public DbContextOptions<TaxonomyContext> _contextOptions { get; set;}
public TestDbContext()
{
// Create and open a connection. This creates the SQLite in-memory database, which will persist until the connection is closed
// at the end of the test (see Dispose below).
_connection = new SqliteConnection("Filename=:memory:");
_connection.Open();
// These options will be used by the context instances in this test suite, including the connection opened above.
_contextOptions = new DbContextOptionsBuilder<TaxonomyContext>()
.UseSqlite(_connection)
.Options;
// Create the schema and seed some data
using var context = new TaxonomyContext(_contextOptions);
if (context.Database.EnsureCreated())
{
using var viewCommand = context.Database.GetDbConnection().CreateCommand();
viewCommand.CommandText = @"
CREATE VIEW AllRequests AS
SELECT Url
FROM Request";
viewCommand.ExecuteNonQuery();
}
var memoryData = new ReqestDataInMemory();
var data = memoryData.AllRepositoryRequests();
context.AddRange(data);
context.SaveChanges();
}
AddRange()
抛出错误
System.InvalidOperationException : The instance of entity type 'RequestType' cannot be tracked because another instance with the same key value for {'RequestTypeId'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.
这是有意义的,如果它试图保存查找表一遍又一遍。这就是我的问题。
这是我正在处理的对象。RequestType
是我遇到阻塞器的地方,它是一个简单的查找表RequestType.Id and RequestType.Name
。Status
是一对多查找表。所有的FK关系都回到Request
ChangeDetail
对象是请求的详细信息。它具有唯一的ID和请求的FK。
我试着将RequestType
和Statuses
都设为空,但它
public class Request
{
public int RequestId { get; set; }
/// <summary>changed from "navarchar(max)" to "text" for sqlite testing db </summary>
[Required]
[MinLength(50)]
[Column(TypeName = "text")]
public string Justification { get; set; } = string.Empty;
[Required]
public int SubmitUser { get; set; }
[Required]
public DateTime SubmitDate { get; set; }
public int? ModifyUser { get; set; }
public DateTime? ModifyDate { get; set; }
public virtual IEnumerable<ChangeDetail> ChangeDetail { get; set; } = new List<ChangeDetail>();
public virtual IEnumerable<Status> Statuses { get; set; } = new List<Status>();
public virtual RequestType RequestType { get; set; } = new RequestType();
}
我的查询工作很好,所以我认为我所有的关系都很稳固。为了以防万一,这里有一些关系。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Request>()
.HasOne(x => x.RequestType)
.WithMany(x => x.Requests);
modelBuilder.Entity<Request>()
.HasMany(x => x.ChangeDetail)
.WithOne(x => x.Request);
modelBuilder.Entity<Request>()
.HasMany(x => x.Statuses)
.WithMany(x => x.Requests);
modelBuilder.Entity<Status>()
.HasOne(x => x.RequestStatusType)
.WithMany(x => x.Statuses);
}
为了解决这个问题,我尝试了这个:LINQ query to return distinct field values from list of objects
我认为这显示了承诺,使用实体。未修改,但不能让它工作Save detached entity in Entity Framework 6
这谈到的FK,我有设置,但也许它没有参考他们保存?How do I stop Entity Framework from trying to save/insert child objects?
我很感激你的任何建议。
1条答案
按热度按时间mwg9r5ms1#
我想我会把这件事了结的。我花了一段时间,但这是多对多关系连接表中的一个数据问题。一旦我修好