我正在为 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 并以
IEnumerable
的形式返回复杂的对象结构。然后我尝试将其保存到DbContext
:
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:无法跟踪实体类型“RequestType”的实例,因为已跟踪具有相同键值 {'RequestTypeId'} 的另一个实例。附加现有实体时,请确保仅附加一个具有给定键值的实体实例。
如果它试图一遍又一遍地保存查找表,这是有道理的。这就是我的问题。
这是我正在使用的对象。
RequestType
是我遇到拦截器的地方,它是一个简单的查找表RequestType.Id and RequestType.Name
。 Status
是一对多查找表。所有人都有 FK 关系回到Request
ChangeDetail
对象是有关请求的详细信息。它具有唯一的 ID 和请求的 FK。
我尝试将
RequestType
和 Statuses
都置为 NULL,但它
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 查询从对象列表中返回不同的字段值
我认为这显示出希望,使用 Entity.Unmodified 但无法让它工作 在实体框架 6 中保存分离实体
这谈论的是 FK,我已经设置了它,但也许它在保存时没有引用它们?
我感谢您提出的任何建议。
我想我会结束这个循环。我花了一段时间,但这是多对多关系的连接表之一中的数据问题。一旦我修复了