内存中的EF核心,删除提供错误的单元测试:实体已被跟踪

时间:2019-05-10 19:21:04

标签: entity-framework-core in-memory-database

我正在使用内存中的实体框架核心来测试我的代码。我在内存上下文中创建并添加了数据。我有删除方法,它将删除ID = 1的记录。测试方法在错误之后引发错误:

  

无法跟踪实体类型'cats'的实例,因为已经跟踪了另一个键值为'{Id:204}'的实例在附加现有实体时,请确保仅附加一个具有给定键值的实体实例

任何人都可以帮助我,如何解决此问题。我在互联网上尝试了不同的方案,但没有任何效果。

Test.cs:

   [Fact(DisplayName ="Delete Service Must Return Result")]
    public void DeleteService()
    {
        var serviceId = _collectionFixture.context.cat.Where(x => x.Id == 201).AsNoTracking();

       var okObject = _collectionFixture.CatController.DeleteService(serviceId) as OkObjectResult;

          var baseResponse = okObject.Value as BaseResponse;
           Assert.True(baseResponse.Success);
    }

我的服务等级:

public catResponse DeleteService(int serviceId)           {                尝试{

               var serviceDto = _Context.catserviceTreatment.Where(x => x.Id 
                           ==serviceId).AsNoTracking().firstordefault();

            if(serviceDto!=null)
            {


                    this._Context.catserviceTreatment.Remove(serviceDto);
                    this._Context.SaveChanges();

                   return new catResponse { Success = true, Error = "service 
                              deleted successfully" };
            }

           }catch(exception e)
           {
           } 
      }

我的收藏夹:

      public catContext GetDbContext()
              {
                  var options = new DbContextOptionsBuilder<catContext>()
                 .UseInMemoryDatabase(Guid.NewGuid().ToString())

               .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)

                  .ConfigureWarnings(x => 
                 x.Ignore(InMemoryEventId.TransactionIgnoredWarning))
               //  .ConfigureWarnings(x=>x.Ignore(InMemoryEventId.))
                .EnableSensitiveDataLogging()
                   .Options;

                var context = new CatDirectoryContext(options);

            var catCategory = new List<catcategory>()
               {
                   new catCategory{Id=100,CategoryName="Youth 
                teereafjkd",UpdatedBy="Test",UpdatedWhen=DateTime.Now},
                 new catCategory{Id=101,CategoryName="Adult 
                fdsafd",UpdatedWhen=DateTime.Now},     
        };

        context.catcategory.AddRange(catCategory);
        context.SaveChanges();


        var catService = new List<catserviceTreatment>()
        {
            new catserviceTreatment{Id=200,Name="House of 
          Hope",Company="",
                Address ="2001 st street",City="alone 
           city",State="UT",ZipCode=8404,Category=null,
                CategoryId =100,Description="this is 
           description",UpdatedBy="test",UpdatedWhen=DateTime.Now},

            new catserviceTreatment{Id=201,Name="Odyssey 
             House",Company="",
                Address ="2001 st",City="bare 
               city",State="UT",ZipCode=84dfd,Category=null,
                CategoryId =101,Description="this is d 
                 description",UpdatedBy="test",UpdatedWhen=DateTime.Now},

        }
        context.catserviceTreatment.AddRange(catService);

        context.SaveChanges();

        return context;

   }

2 个答案:

答案 0 :(得分:0)

很可能您进行了一些查询,然后浏览该查询的结果并尝试删除找到的项目。 像这样:

var catsToDelete = myContext.Cats
        .Where(cat => cat.Id == 204);

foreach (var cat in catsToDelete) {
    myContext.Cats.Remove(cat);
}

以这种方式将无法正常工作,因为实体框架仍会跟踪每个项目。

为避免该跟踪,您需要在LINQ查询的末尾添加ToList()AsNoTracking()调用:

var catsToDelete = myContext.Cats
        .Where(cat => cat.Id == 204)
        .AsNoTracking();

foreach (var cat in catsToDelete) {
    myContext.Cats.Remove(cat);
}

答案 1 :(得分:0)

我有同样的错误。 在安装过程中,我添加了一些以ID 1开头的测试记录。 似乎当添加新记录时,内存数据库也从1开始编号,从而导致“实体已被跟踪”错误。

在我更改初始化代码以使用从101开始的id之后,问题得以解决。