Entity framework core EF Core更新实体类型的实例';Ads&x27;无法跟踪

Entity framework core EF Core更新实体类型的实例';Ads&x27;无法跟踪,entity-framework-core,xunit,Entity Framework Core,Xunit,我试图为Asp.net Core DBContext实现一个XUnit测试,但出现以下错误 消息:System.InvalidOperationException:无法跟踪实体类型“Ads”的实例,因为已在跟踪具有相同密钥的此类型的另一个实例。添加新实体时,对于大多数键类型,如果未设置键(即,如果为键属性指定了其类型的默认值),则将创建唯一的临时键值。如果要显式设置新实体的键值,请确保它们不会与现有实体或为其他新实体生成的临时值冲突。附加现有实体时,请确保只有一个具有给定键值的实体实例附加到上下

我试图为Asp.net Core DBContext实现一个XUnit测试,但出现以下错误

消息:System.InvalidOperationException:无法跟踪实体类型“Ads”的实例,因为已在跟踪具有相同密钥的此类型的另一个实例。添加新实体时,对于大多数键类型,如果未设置键(即,如果为键属性指定了其类型的默认值),则将创建唯一的临时键值。如果要显式设置新实体的键值,请确保它们不会与现有实体或为其他新实体生成的临时值冲突。附加现有实体时,请确保只有一个具有给定键值的实体实例附加到上下文

这是我目前的代码:

    public class AdsServiceTest
{
    private readonly DbContextOptions<SensingSiteDbContext> _options;
    private readonly SensingSiteDbContext _context;
    private readonly AdsService _AdsService;
    public AdsServiceTest()
    {
        //initialize db options
        _options = new DbContextOptionsBuilder<SensingSiteDbContext>()
            .UseInMemoryDatabase()
            .Options;
        //get service
        _context = new SensingSiteDbContext(_options);
            //initialize dbcontext
            List<Ads> listAds = new List<Ads>() {
                new Ads(){  Id=1,AdsName="Ads1", Deleted=false},
                new Ads(){  Id=2,AdsName="Ads1", Deleted=false},
                new Ads(){  Id=3,AdsName="Ads1", Deleted=false}
            };
         _context.Advertisements.AddRange(listAds);
            //context.Advertisements
            BaseLib.SSDbContext<Ads, AdsService> ssDbContent = new BaseLib.SSDbContext<Ads, AdsService>(_context);
            _AdsService = ssDbContent.GetService((x, y) => new AdsService(x, y));

    }
    [Theory]
    [InlineData(1)]
    public void FindById(int id)
    {
        Ads adsResult = _AdsService.FindById(id);
        Ads adsTarget = _context.Advertisements.Find(adsResult.Id);
        Assert.True(adsTarget.Equals(adsResult));
    }
    //Failed by error System.InvalidOperationException : The instance of entity type 'Ads' cannot be tracked because another instance of this type with the same key is already being tracked
    [Fact]
    public void Update()
    {
        Ads adsResult = new Ads() { Id = 1, AdsName = "UpdateAds1" };
        _AdsService.UpdateAds(adsResult);
        Ads adsTarget = _context.Advertisements.Find(adsResult.Id);
        Assert.True(adsTarget.Equals(adsResult));
    }
}

任何帮助都将不胜感激。

您正在创建自己的实体,您应该从上下文中获取已添加的实体:

Ads adsResult = new Ads() { Id = 1, AdsName = "UpdateAds1" };
_AdsService.UpdateAds(adsResult);
在这段代码中,实体框架会说,“嘿,我已经有了一个具有该键的实体(检查您的构造函数,您正在使用相同的Id放入一个实体),但是这个对象;我不知道如何处理它(因为它来自外部,并且已经存在一个键)”

您可以将其更改为您在上一次测试中正在执行的操作:

Ads adsResult = _AdsService.FindById(id);
//do your changing here
_AdsService.UpdateAds(adsResult);

您正在创建自己的实体,这时,您应该从上下文中获取已添加的实体:

Ads adsResult = new Ads() { Id = 1, AdsName = "UpdateAds1" };
_AdsService.UpdateAds(adsResult);
在这段代码中,实体框架会说,“嘿,我已经有了一个具有该键的实体(检查您的构造函数,您正在使用相同的Id放入一个实体),但是这个对象;我不知道如何处理它(因为它来自外部,并且已经存在一个键)”

您可以将其更改为您在上一次测试中正在执行的操作:

Ads adsResult = _AdsService.FindById(id);
//do your changing here
_AdsService.UpdateAds(adsResult);

你的意思是我不能使用
\u dbSet.Update(实体)?在我的选项中,当我使用
entity.ObjectState=ObjectState.Modified
时,它可以接受一个新对象。否则,我将需要逐个设置该字段。问题不在于
\u dbSet.Update(entity)
调用,而在于您在上下文中使用的对象。您可以更改更新测试中使用的
new Ads()
以从上下文中检索它,或者,您可以执行您正在执行的操作,然后首先调用
context.Attach(entity)
,以便EF可以协调您从外部传入的对象。您的意思是我不能使用
\u dbSet.update(entity)?在我的选项中,当我使用
entity.ObjectState=ObjectState.Modified
时,它可以接受一个新对象。否则,我将需要逐个设置该字段。问题不在于
\u dbSet.Update(entity)
调用,而在于您在上下文中使用的对象。您可以更改更新测试中使用的
new Ads()
以从上下文中检索它,或者,您可以执行您正在执行的操作,然后首先调用
context.Attach(entity)
,以便EF可以协调您从外部传入的对象。