繁体   English   中英

EF Core(内存数据库)-'无法跟踪实体类型 X 的实例,因为另一个具有键值的实例

[英]EF Core (in-memory database) - 'The instance of entity type X cannot be tracked because another instance with the key value

我正在将 xunit 与 Entity Framework 内存数据库一起使用。 对于每个测试,我在 memory 数据库中创建一个新实例,然后进行处理。

运行超过 1 个测试时出现以下错误。

System.InvalidOperationException:“无法跟踪实体类型“Account_Master”的实例,因为已在跟踪另一个具有键值“{NUMBER_INT:1}”的实例。 附加现有实体时,请确保仅附加一个具有给定键值的实体实例。

据我所知,当我尝试用假测试数据填充我的内存数据库时,问题就出现了。 在第一个测试中,我添加了一个虚拟帐户和一个虚拟 scope(这些由外键引用)。 这工作正常。

但是在下一次测试中,当我添加虚拟 scope 时,它会自动添加虚拟帐户(即使它还不应该知道)。

我在这里有一个示例代码项目https://github.com/welcometochristown/efCoreErrorTest

我在这个项目中有两个数据库上下文

FakeAccountContext
FakeSmtrSimpleContext

出于某种原因, FakeAccountContext有效,但FakeSmtrSimpleContext无效(即使它们几乎相同)。

重现错误

Build project
Open the test explorer
Expand tests
Right click "SmtrSimpleTest" -> Run (error!)
Right click "AccountTest" -> Run (works!)

使用 Microsoft.EntityFrameworkCore.InMemory (3.1.27)

我认为关于 static 属性在测试之间保持对实体的引用的假设是正确的。

在调试器中,在第二次测试中,在Account_Master.Add()之前的断点中,我们可以看到之前测试的 static SmtrSimpleDummyAccount (一个Account_Master )仍然存在:

调试器显示显示 Account_Master 在添加之前存在

我将 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",
            };
        }
    }

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)
            };
        }

    }

现在所有的测试都通过了:

测试通过

可能也与您的FakeAccount.SmtrSimpleDummyAccount相关: 如何创建 static lambda 以用于表达式构建?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM