EF Core в памяти, удаление модульного тестирования с ошибкой: объект уже отслежен - PullRequest
0 голосов
/ 10 мая 2019

Я работаю с ядром платформы сущностей в памяти, чтобы проверить мой код. Я создал в контексте памяти и добавил данные. У меня есть метод удаления, который собирается удалить запись с 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 голосов
/ 09 июля 2019

У меня была такая же ошибка.Во время установки я добавил несколько тестовых записей, начиная с идентификатора 1. Оказалось, что база данных в памяти также начинает нумерацию с 1 при добавлении новых записей, что вызывает ошибку «сущность уже отслежена».

После того, как я изменил свою инициализациюкод для использования идентификаторов с 101, проблема была решена.

0 голосов
/ 11 мая 2019

Скорее всего, вы сделали какой-то запрос, а затем пролистали результаты этого запроса и попытались удалить найденные элементы.Что-то вроде:

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

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

Это не будет работать таким образом, потому что каждый элемент все еще отслеживается Entity Framework.

Чтобы избежать этого отслеживания, вам нужно либо добавить ToList() или AsNoTracking()вызов в конце запроса LINQ:

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

foreach (var cat in catsToDelete) {
    myContext.Cats.Remove(cat);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...