[英]EF Core (in-memory database) - 'The instance of entity type X cannot be tracked because another instance with the key value
I am using xunit with an Entity Framework in-memory database.我正在将 xunit 与 Entity Framework 内存数据库一起使用。 For each test a new instance of my in memory database is created and then disposed.
对于每个测试,我在 memory 数据库中创建一个新实例,然后进行处理。
I get the following error when running more than 1 tests.运行超过 1 个测试时出现以下错误。
System.InvalidOperationException: 'The instance of entity type 'Account_Master' cannot be tracked because another instance with the key value '{NUMBER_INT: 1}' is already being tracked.
System.InvalidOperationException:“无法跟踪实体类型“Account_Master”的实例,因为已在跟踪另一个具有键值“{NUMBER_INT:1}”的实例。 When attaching existing entities, ensure that only one entity instance with a given key value is attached.'
附加现有实体时,请确保仅附加一个具有给定键值的实体实例。
From what I can see the issue arises when I try and populate my in-memory database with fake test data.据我所知,当我尝试用假测试数据填充我的内存数据库时,问题就出现了。 On the first test, I add an dummy account, and a dummy scope (these are referenced by foreign key).
在第一个测试中,我添加了一个虚拟帐户和一个虚拟 scope(这些由外键引用)。 This works fine.
这工作正常。
However on the next test, when I add the dummy scope, it automatically adds the dummy account (even though it should not know about it yet).但是在下一次测试中,当我添加虚拟 scope 时,它会自动添加虚拟帐户(即使它还不应该知道)。
I have an example code project here https://github.com/welcometochristown/efCoreErrorTest我在这里有一个示例代码项目https://github.com/welcometochristown/efCoreErrorTest
I have two database contexts in this project我在这个项目中有两个数据库上下文
FakeAccountContext
FakeSmtrSimpleContext
For some reason the FakeAccountContext
works, but the FakeSmtrSimpleContext
doesn't (even though they are nearly identical).出于某种原因,
FakeAccountContext
有效,但FakeSmtrSimpleContext
无效(即使它们几乎相同)。
To reproduce error重现错误
Build project
Open the test explorer
Expand tests
Right click "SmtrSimpleTest" -> Run (error!)
Right click "AccountTest" -> Run (works!)
Using Microsoft.EntityFrameworkCore.InMemory (3.1.27)使用 Microsoft.EntityFrameworkCore.InMemory (3.1.27)
I think the hypothesis about the static properties maintaining references to the entities between tests is correct.我认为关于 static 属性在测试之间保持对实体的引用的假设是正确的。
In the debugger, on the second test, in a breakpoint before the Account_Master.Add()
, we can see that the static SmtrSimpleDummyAccount
(an Account_Master
) of the previous test still exists:在调试器中,在第二次测试中,在
Account_Master.Add()
之前的断点中,我们可以看到之前测试的 static SmtrSimpleDummyAccount
(一个Account_Master
)仍然存在:
I changed the static properties to methods that return a new object, then forget it instead of maintaining a static reference to it:我将 static 属性更改为返回新 object 的方法,然后忘记它,而不是维护对它的 static 引用:
public static class FakeAccount
{
public static Account DummyAccount()
{
return new Account
{
NUMBER_INT = 1,
SCOPE_CHR = FakeAccountScope.Public().SCOPE_CHR
};
}
public static Account_Master SmtrSimpleDummyAccount()
{
return new Account_Master
{
NUMBER_INT = 1,
SCOPE_CHR = "Public",
};
}
}
and和
public static class FakeAccountScope
{
public static AccountScope Private()
{
return new AccountScope
{
SCOPE_CHR = nameof(Private)
};
}
public static AccountScope Public()
{
return new AccountScope
{
SCOPE_CHR = nameof(Public)
};
}
public static X_Account_Scope SmtrSimplePublic()
{
return new X_Account_Scope
{
SCOPE_CHR = nameof(Public)
};
}
public static X_Account_Scope SmtrSimplePrivate()
{
return new X_Account_Scope
{
SCOPE_CHR = nameof(Private)
};
}
}
And now all the tests pass:现在所有的测试都通过了:
Possibly also relevant for your FakeAccount.SmtrSimpleDummyAccount
: How to create a static lambda for use with expression building?可能也与您的
FakeAccount.SmtrSimpleDummyAccount
相关: 如何创建 static lambda 以用于表达式构建?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.