簡體   English   中英

無法跟蹤實體類型“ TestType”的實例,因為已經跟蹤了具有相同鍵的該類型的另一個實例

[英]The instance of entity type 'TestType' cannot be tracked because another instance of this type with the same key is already being tracked

嘗試執行以下操作時,出現以下異常:

    context.Entry(testType).State = EntityState.Modified;


System.InvalidOperationException: The instance of entity type 'TestType' cannot be tracked because another instance of this type with the same key is already being tracked. When adding new entities, for most key types a unique temporary key value will be created if no key is set (i.e. if the key property is assigned the default value for its type). If you are explicitly setting key values for new entities, ensure they do not collide with existing entities or temporary values generated for other new entities. When attaching existing entities, ensure that only one entity instance with a given key value is attached to the context.
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(TKey key, InternalEntityEntry entry)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(InternalEntityEntry entry)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.StartTracking(InternalEntityEntry entry)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState oldState, EntityState newState, Boolean acceptChanges)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState entityState, Boolean acceptChanges)
   at Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry.set_State(EntityState value)

我沒有看到任何代碼,其中已經跟蹤了另一個具有相同鍵的TestType實例!

來自數據庫的測試類型通過.AsNoTracking();加載.AsNoTracking();

因此,在此代碼中的哪里有我具有RemoveRange / AddRange操作的具有相同鍵的TestType實例? 那意味着我的TestTypeComparer壞了嗎?

我在這里嘗試做的是讓用戶一次性保存已更改/添加/刪除的實體:

 public async Task<IEnumerable<TestType>> SaveTestTypesAsync(List<TestType> testTypes, int schoolyearId, int schoolclassId, int subjectId)
        {
            var testTypesFromDatabase = await context.TestTypes
                                          .Include(t => t.Subject)
                                          .Include(s => s.Schoolclass)
                                          .Where(p =>
                                          p.Schoolclass.Id == schoolclassId &&
                                          p.Subject.Id == subjectId)
                                          .AsNoTracking()
                                          .ToListAsync();

            var schoolclass = new Schoolclass { Id = schoolclassId };
            var subject = new Subject { Id = subjectId };
            var schoolyear = new Schoolyear { Id = schoolyearId };
            foreach (var testType in testTypes)
            {
                testType.Schoolclass = schoolclass;
                testType.Subject = subject;
                testType.Schoolyear = schoolyear;
            }

            var testTypesToRemove = testTypesFromDatabase.Except(testTypes, new TestTypeComparer()).ToList();
            context.TestTypes.RemoveRange(testTypesToRemove);

            var testTypesToAdd = testTypes.Where(t => t.Id == 0).ToList();  // 
            context.TestTypes.AddRange(testTypesToAdd);

            var modifiedTestTypesToUpdate = testTypes.Except(testTypesToAdd.Concat(testTypesToRemove).ToList(), new TestTypeComparer()).ToList();
            foreach (var testType in modifiedTestTypesToUpdate)
            {
                context.Entry(testType).State = EntityState.Modified;
            }

            context.Attach(schoolclass);      
            context.Attach(subject);
            context.Attach(schoolyear);

            await context.SaveChangesAsync();

            return await this.GetTestTypesConfigurationAsync(schoolclassId, subjectId);
        }


public class TestTypeComparer : IEqualityComparer<TestType>
{
    public bool Equals(TestType x, TestType y)
    {
        return x.Id == y.Id;
    }

    public int GetHashCode(TestType obj)
    {
        return obj.Id.GetHashCode();
    }
}

public class TestType
    {
        public TestType()
        {
            Tests = new HashSet<Test>();
        }

        public int Id { get; set; }
        public string Name { get; set; }
        public int Weight { get; set; }
        public ISet<Test> Tests { get; set; }
        public Schoolyear Schoolyear { get; set; }  
        public Schoolclass Schoolclass { get; set; }
        public int SchoolclassId { get; set; }
        public Subject Subject { get; set; }
        public int SubjectId { get; set; }
        public int SchoolyearId { get; set; }
    }

任何人都可以幫助我,但我無法找到具有相同密鑰的雙重跟蹤實體。

我只是假設問題與確定我添加/修改/刪除的實體有關。

UPDATE

我現在已經在設置State.Modified為所有TestTypesToUpdate之前記錄了所有跟蹤器更改:

State: Deleted | Type: TestType | Id-Value: 12
State: Unchanged | Type: Schoolclass | Id-Value: 1
State: Unchanged | Type: TestType | Id-Value: 8
State: Unchanged | Type: Subject | Id-Value: 1
State: Deleted | Type: TestType | Id-Value: 13
State: Added | Type: TestType | Id-Value: -2147482647
State: Detached | Type: Schoolclass | Id-Value: 1
State: Added | Type: Schoolyear | Id-Value: 1
State: Detached | Type: Subject | Id-Value: 1
State: Added | Type: TestType | Id-Value: -2147482646

看來是的...已經跟蹤了某些實體。 似乎我必須在變更跟蹤器上進行其他投資,然后再決定要怎么做。

但我不敢相信我是第一個這樣做的人,還沒有在Google上找到任何東西。

考慮了多個具有相同鍵問題的實例后,我再次重新排列了代碼,直到再次出現錯誤為止,我無法將testTypeToUpdate的狀態設置為state.Modified,因為SchoolclassId是鍵的一部分。

好吧...然后我搜索了流暢的遷移結果,發現了這一點:

modelBuilder.Entity<TestType>().HasAlternateKey(x => new { x.Name, x.SchoolclassId, x.SubjectId });

我前一陣子做了(但從未測試過-真可惜-),我認為它的EF6等同於Index Attribute ...因為那是我想要的功能!

然后我用谷歌搜索並創建了一些新的東西:

modelBuilder.Entity<TestType>().HasIndex(p => new { p.Name, p.SchoolclassId, p.SubjectId} ).IsUnique();

現在我有了我想要的!

我還刪除了分配給testTypesToRemove的schoolclass,subject和schoolyear實例,這也創建了一些奇怪的東西...

該代碼現在可以工作:

   public async Task<IEnumerable<TestType>> SaveTestTypesAsync(List<TestType> testTypes, int schoolyearId, int schoolclassId, int subjectId)
        {
            var testTypesFromDatabase = await context.TestTypes
                                          .Include(t => t.Subject)
                                          .Include(s => s.Schoolclass)
                                          .Where(p =>
                                          p.Schoolclass.Id == schoolclassId &&
                                          p.Subject.Id == subjectId)
                                          .AsNoTracking()
                                          .ToListAsync();

            var schoolclass = new Schoolclass { Id = schoolclassId };
            var subject = new Subject { Id = subjectId };
            var schoolyear = new Schoolyear { Id = schoolyearId };

            // Make the navigation properties available during SaveChanges()
            context.Attach(schoolclass);
            context.Attach(subject);
            context.Attach(schoolyear);

            // DELETE
            var testTypesToRemove = testTypesFromDatabase.Except(testTypes, new TestTypeComparer()).ToList();
            context.TestTypes.RemoveRange(testTypesToRemove);

            // ADD
            var testTypesToAdd = testTypes.Where(t => t.Id == 0).ToList();  // 
            foreach (var testType in testTypesToAdd)
            {
                testType.Schoolclass = schoolclass;
                testType.Subject = subject;
                testType.Schoolyear = schoolyear;
            }
            context.TestTypes.AddRange(testTypesToAdd);

            // UPDATE
            var modifiedTestTypesToUpdate = testTypes.Except(testTypesToAdd.Concat(testTypesToRemove).ToList(), new TestTypeComparer()).ToList();
            foreach (var testType in modifiedTestTypesToUpdate)
            {
                testType.Schoolclass = schoolclass;
                testType.Subject = subject;
                testType.Schoolyear = schoolyear;
            }   
            context.UpdateRange(modifiedTestTypesToUpdate);

            await context.SaveChangesAsync();

            return await this.GetTestTypesConfigurationAsync(schoolclassId, subjectId);
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM