EF Core - дочерний экземпляр отслеживается, даже если родительский объект удален - PullRequest
0 голосов
/ 08 мая 2020

Я пишу тесты xUnit для проверки моих. NET методов Core API Controller. Я хотел бы получить объект Case с помощью метода Get, манипулировать им внутри тестовой функции (имитируя действия пользователя) и обновить его с помощью метода PUT. Вот модель:

 public class Case
    {
        public int CaseId { get; set; }
        public string CaseNo { get; set; }
        public List<CaseAccessCodes> AccessCodes { get; set; }
    }
public class CaseAccessCodes
{
    [Key]
    public int CaseAccessCodesId { get; set; }
    [ForeignKey("Case")]
    public int CaseId { get; set; }
    public Case Case { get; set; }
    [ForeignKey("AccessCode")]
    public int AccessCodeId { get; set; }
    public AccessCode AccessCode { get; set; }
}

Вот метод тестового начального числа и метод тестирования:

public CasesControllerTests() //context to seed the database first
        {
            var options = new DbContextOptionsBuilder<CaseflowingContext>()
                .UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString()) //so the database names are unique for each test run.
                .Options;


            _context = new CaseflowingContext(options, null);
            _context.Database.EnsureCreated();

            Case @case = new Case { CaseGroupId = 1, CaseStateId = 1, CaseTypeId = 1, Title = "TestCase" };
            _context.Cases.Add(@case);
            List<CaseAccessCodes> cac = new List<CaseAccessCodes>
            {
                new CaseAccessCodes{CaseAccessCodesId= 1, AccessCodeId = 1, CaseId = 1},
                new CaseAccessCodes{CaseAccessCodesId= 2, AccessCodeId = 2, CaseId = 1}
            };
            _context.CaseAccessCodes.AddRange(cac);
            _context.SaveChanges();
        }

        [Fact]
        public async void CaseAccessCodesDeletion()
        {
            CasesController cc = new CasesController(_context, null);

            var @case = cc.GetCase(1).Result.Value;
            _context.Entry(@case).State = EntityState.Deleted;
            var detachedCase = new Case();
            detachedCase = @case;
            detachedCase.AccessCodes.RemoveAll(x => x.CaseAccessCodesId == 2);
            detachedCase.AccessCodes.Find(x => x.CaseAccessCodesId == 1).AccessCode = null;

            await cc.PutCase(1, detachedCase);

            _context.SaveChanges();

            var newCase = cc.GetCase(1).Result.Value;

            Assert.Equal(1, newCase.AccessCodes.Count);
        }

Раньше, когда я пытался это сделать, была ошибка:

"Экземпляр типа сущности 'Case' не может быть отслежен, потому что другой экземпляр с таким же значением ключа для {'CaseId'} уже отслеживается. При присоединении существующих сущностей убедитесь, что только один экземпляр сущности с заданным значением ключа прилагается. Рассмотрите возможность использования 'DbContextOptionsBuilder.EnableSensitiveDataLogging', чтобы увидеть конфликтующие значения ключей. "

Вот почему я вставил строку

_context.Entry(@case).State = EntityState.Deleted; 

. Но теперь то же самое происходит, также внутри метода PUT, но с CaseAccessCodes:

«Экземпляр типа сущности 'CaseAccessCodes' не может быть отслежен, потому что другой экземпляр с таким же значением ключа для {'CaseAccessCodesId' } уже отслеживается. При присоединении существующих сущностей убедитесь, что присоединен только один экземпляр сущности с заданным значением ключа. Рассмотрите возможность использования 'DbContextOptionsBuilder.EnableSensitiveDataLogging', чтобы увидеть конфликтующие значения ключей. "

Это исключение возникает при выполнении следующей строки внутри метода PUT:

_context.Entry(caseAccessCode).State = EntityState.Deleted;

Итак, в основном я делаю кое-что для отслеживания CaseAccessCodes внутри метода PUT, и он отлично работает при обычном вызове API, но когда я выполнить это из тестового метода, он не работает с вышеуказанной ошибкой. Как я могу полностью отделить все, что связано с этим тестовым примером, и просто использовать его в качестве входных данных для метода PUT?

...