无法跟踪类型为'Entity'的实体,因为已经通过更新实体解决了另一个具有相同'{'Id'}键值的实例

时间:2018-12-15 18:21:38

标签: .net asp.net-mvc entity-framework unit-testing

我所面对的就像大多数人都遇到上述问题。在我查找的一个线程中,解决方案非常简单:使用相同的上下文实例,添加并声明并将SUT置于其保护之下。像这样:

        //Act
        using (var actContext = new ItsAllAboutTheGameDbContext(contextOptions))
        {
            await actContext.Users.AddAsync(user);
            await actContext.Wallets.AddAsync(userWallet);
            await actContext.CreditCards.AddAsync(creditCard);
            await actContext.SaveChangesAsync();
            var sut = new TransactionService(actContext, walletServiceMock.Object,
                userServiceMock.Object, foreignExchangeServiceMock.Object, cardServiceMock.Object, dateTimeProvider);
            var transactionDTO = await sut.MakeDeposit(user, creditCard.Id, amount);

            Assert.IsInstanceOfType(transactionDTO, typeof(TransactionDTO));
        }

好吧,这不能给我一个很好的答案,因为这不是通常的做法,因为我们对所有实例都使用相同的上下文选项,例如:

//Act
        using (var actContext = new ItsAllAboutTheGameDbContext(contextOptions))
        {
            await actContext.Users.AddAsync(user);
            await actContext.Wallets.AddAsync(userWallet);
            await actContext.CreditCards.AddAsync(creditCard);
            await actContext.SaveChangesAsync();
        }

        //Assert
        using (var assertContext = new ItsAllAboutTheGameDbContext(contextOptions))
        {
            var sut = new TransactionService(assertContext, walletServiceMock.Object,
                userServiceMock.Object, foreignExchangeServiceMock.Object, cardServiceMock.Object, dateTimeProvider);
            assertContext.CreditCards.Update(creditCard);
            var transactionDTO = await sut.MakeDeposit(user, creditCard.Id, amount);

            Assert.IsInstanceOfType(transactionDTO, typeof(TransactionDTO));
        }

但这不起作用!它在主题异常中抛出了上述问题!实体被添加2次(是的,是同一实体的副本)。我现在遇到的一个奇怪的解决方案是,在继续进行被测系统之前先更新Entity(CreditCard)。像这样:

assertContext.CreditCards.Update(creditCard);
            var transactionDTO = await sut.MakeDeposit(user, creditCard.Id, amount);

由于有了更新,我想跟踪对您有所帮助。我需要阅读更多有关Entity Framework或其他Framework的文档是一回事,有人可以给我一个很简单的答案来说明为什么在这两种情况下都行得通,哪一种是首选的,如果两者都确实是,并且有一个解决方案,而不同时执行两者之一,那会是什么? 预先感谢!

更新

我注意到,当我甚至开始以任何方式跟踪实体时,例如附加它,因为我不想以任何不需要的方式对其进行修改,它就可以工作!因此,我猜想由于Update以一种方式跟踪给定的Entity并以另一种方式跟踪Attach,因此我猜想首先没有跟踪Entity。即使将TrackBehaviour设置为true,我也确实需要一些确认,以便我们可以关闭该线程或将我的答案标记为true

0 个答案:

没有答案