1

由於實體子項具有複合主鍵,也是外鍵的一部分,所以我在將子實體從父代轉移到另一個時遇到問題如果屬性值相同,則將值設置爲未修改

從技術上講它相同的問題 Entity Framework: Cancel a property change if no change in value

但是,從有8年過去了,還有一些其他的解決方案,現在應該存在?

,我想出了迄今爲止最好的解決辦法是這樣的:

public void CleanModified() 
    { 
     foreach (var entityEntry in ChangeTracker.Entries() 
           .Where(w => w.State.HasFlag(EntityState.Modified))) 
     { 
      foreach (var currentValuesPropertyName in entityEntry.CurrentValues 
                    .PropertyNames) 
      { 
       var nop = entityEntry.Property(currentValuesPropertyName); 

       if (!nop.IsModified) 
        continue; 

       if (Object.Equals(nop.CurrentValue, nop.OriginalValue)) 
        nop.IsModified = false; 
      } 
     } 
    } 

可悲的是,這並不工作,只是拋出同樣的例外,我在第一時間得到關於nop.IsModified = false;

The property '[CompositeKeyProperty]' is part of the object's key information 
and cannot be modified 

我沒有任何東西與T4工作,所以我不知道這是否可以幫助我在這種情況下?

增加了以下的例子:

實體

public class Parent 
{ 
    public int TenantId { get; set; } 
    public int Id { get; set; } 

    public virtual ICollection<Child> Children { get; set; } 
} 

public class Child 
{ 
    public int TenantId { get; set; } 
    public int Id { get; set; } 
    public int ParentId { get; set; } 

    public virtual Parent Parent { get; set; } 
} 

映射

public class ParentConfiguration : EntityTypeConfiguration<Parent> 
{ 
    public ParentConfiguration() 
    { 
     HasKey(k => new { k.TenantId, k.Id }); 

     Property(p => p.TenantId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); 

     Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
    } 
} 

public class ChildConfiguration : EntityTypeConfiguration<Child> 
{ 
    public ChildConfiguration() 
    { 
     HasKey(k => new { k.TenantId, k.Id }); 

     Property(p => p.TenantId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); 

     Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 

     HasRequired(r => r.Parent).WithMany(m => m.Children) 
      .HasForeignKey(f => new { f.TenantId, f.ParentId }); 
    } 
} 

計劃

public void Main() 
{ 
    //Just example, fetched from database in real code 
    Parent parentOld = new Parent 
    { 
     TenantId = 1, 
     Id = 1, 
     Children = { new Child { TenantId = 1, Id = 1, ParentId = 1 } } 
    }; 

    Parent parentNew = new Parent { TenantId = 1, Id = 2 }; 

    //Move child from oldParent to newParent 
    foreach (var parentOldChild in parentOld.Children) 
    { 
     //Throws 'The property 'TenantId' is part of the object's key information 
     //and cannot be modified' 
     parentOldChild.Parent = parentNew; 
    } 
} 
+0

你有意外引用相同的'ChangeTracker'對象不止一次檢查修改後的狀態(通過不同的上下文中)?通常這個錯誤發生在foreach循環中,並通過在循環體內分配該對象的新實例來解決。 –

+0

@TetsuyaYamamoto否它是所有在同一個單一上下文和訪問被直接路由到底層的DbContext –

回答

0

錯誤告訴你,這個問題是因爲你試着克至設置字段這是實體的鍵列的部分IsModified狀態。你確定你正在看的實體不是新的嗎?這可能是一個場景,其中的CurrentValue等於OriginalValue,但IsModified仍然是正確的,不能改變。

+0

添加了一些更多示例代碼中,第一個例子代碼試圖恢復更改第二示例casues,通過觸摸「TenantId」它觸發在changetracker –

+0

的變化更新表的鍵TenantId一部分? – ErikE

+0

是的,我已經更新了一個簡化的例子後 –

相關問題