无法跟踪实体类型“ TestType”的实例,因为已经跟踪了具有相同键的该类型的另一个实例

伊丽莎白

当我尝试执行以下操作时,出现以下异常:

    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();

因此,在此代码中的哪里有我具有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; }
    }

任何人都可以帮助我,我无法找到具有相同密钥的重复跟踪实体。

我只是假设问题与确定我添加/修改/删除的实体有关。

更新

我现在已经在设置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);
        }

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类常见问题

Hibernate在另一个实体列表中不包括与实体类型相同的子实体

来自分类常见问题

ASP.NET MVC-附加类型为“ MODELNAME”的实体失败,因为相同类型的另一个实体已经具有相同的主键值

来自分类Dev

201的响应实体类型已创建?

来自分类Dev

“附加类型T的实体失败,因为相同类型的另一个实体已经具有相同的主键值”

来自分类Dev

附加“ X”类型的实体失败,因为另一个相同类型的实体

来自分类Dev

在类中声明属性,该类在C ++中具有另一个类型

来自分类Dev

PHP:管理实体类型的设计模式

来自分类Dev

无法跟踪,因为另一个实例具有相同的键值

来自分类Dev

EF Core:无法跟踪实体类型的实例,因为另一个具有相同键值的实例

来自分类Dev

无法跟踪实体类型“个人资料”的实例,因为已经跟踪了另一个键值为“ {Id:1087}”的实例

来自分类Dev

为什么会出现此异常“附加类型为'Model'的实体失败,因为相同类型的另一个实体已经具有相同的主键值。”

来自分类Dev

具有Automapper的EF Core引发异常“无法跟踪实体类型”

来自分类Dev

无法跟踪实体类型“ x”的实例,因为已经跟踪了具有相同的{'a','b'}键值的另一个实例

来自分类Dev

在Spring Data JPA中保存实体,该实体包含另一个实体类型的列表

来自分类Dev

EF,Automapper异常,“附加类型...的实体失败,因为相同类型的另一个实体已经具有相同的主键值”

来自分类Dev

域驱动设计。实体类型设计

来自分类Dev

如何确定PartyId的实体类型?

来自分类Dev

宁静的设计实体类型。

来自分类Dev

EF Core 更新无法跟踪实体类型“广告”的实例

来自分类Dev

一个实体引用 2 个相同实体类型的实体关系?

来自分类Dev

Symfony 表单验证实体类型

来自分类Dev

无法加载,因为已经加载了另一个具有相同文件的 AssetBundle

来自分类Dev

无法跟踪实体类型 <T> 的实例,因为已跟踪另一个具有相同 {'Id'} 键值的实例

来自分类Dev

附加类型为“XXX”的实体失败,因为同一类型的另一个实体已具有相同的主键值

来自分类Dev

附加“ModelName”类型的实体失败,因为另一个相同类型的实体已经具有相同的主键值

来自分类Dev

ASP.NET Core - 无法跟踪实体类型的实例

来自分类Dev

SDN 参数化关系实体类型

来自分类Dev

播种数据库时无法跟踪实体类型“分配”的实例

来自分类Dev

“如何修复“实体类型的实例”无法跟踪,因为另一个具有键值“{TypeId: 1}”的实例已被跟踪。

Related 相关文章

  1. 1

    Hibernate在另一个实体列表中不包括与实体类型相同的子实体

  2. 2

    ASP.NET MVC-附加类型为“ MODELNAME”的实体失败,因为相同类型的另一个实体已经具有相同的主键值

  3. 3

    201的响应实体类型已创建?

  4. 4

    “附加类型T的实体失败,因为相同类型的另一个实体已经具有相同的主键值”

  5. 5

    附加“ X”类型的实体失败,因为另一个相同类型的实体

  6. 6

    在类中声明属性,该类在C ++中具有另一个类型

  7. 7

    PHP:管理实体类型的设计模式

  8. 8

    无法跟踪,因为另一个实例具有相同的键值

  9. 9

    EF Core:无法跟踪实体类型的实例,因为另一个具有相同键值的实例

  10. 10

    无法跟踪实体类型“个人资料”的实例,因为已经跟踪了另一个键值为“ {Id:1087}”的实例

  11. 11

    为什么会出现此异常“附加类型为'Model'的实体失败,因为相同类型的另一个实体已经具有相同的主键值。”

  12. 12

    具有Automapper的EF Core引发异常“无法跟踪实体类型”

  13. 13

    无法跟踪实体类型“ x”的实例,因为已经跟踪了具有相同的{'a','b'}键值的另一个实例

  14. 14

    在Spring Data JPA中保存实体,该实体包含另一个实体类型的列表

  15. 15

    EF,Automapper异常,“附加类型...的实体失败,因为相同类型的另一个实体已经具有相同的主键值”

  16. 16

    域驱动设计。实体类型设计

  17. 17

    如何确定PartyId的实体类型?

  18. 18

    宁静的设计实体类型。

  19. 19

    EF Core 更新无法跟踪实体类型“广告”的实例

  20. 20

    一个实体引用 2 个相同实体类型的实体关系?

  21. 21

    Symfony 表单验证实体类型

  22. 22

    无法加载,因为已经加载了另一个具有相同文件的 AssetBundle

  23. 23

    无法跟踪实体类型 <T> 的实例,因为已跟踪另一个具有相同 {'Id'} 键值的实例

  24. 24

    附加类型为“XXX”的实体失败,因为同一类型的另一个实体已具有相同的主键值

  25. 25

    附加“ModelName”类型的实体失败,因为另一个相同类型的实体已经具有相同的主键值

  26. 26

    ASP.NET Core - 无法跟踪实体类型的实例

  27. 27

    SDN 参数化关系实体类型

  28. 28

    播种数据库时无法跟踪实体类型“分配”的实例

  29. 29

    “如何修复“实体类型的实例”无法跟踪,因为另一个具有键值“{TypeId: 1}”的实例已被跟踪。

热门标签

归档