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; 
      } 
     } 
    } 

悲しいことに、このdoesntの仕事とちょうど私が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」オブジェクトを2回以上参照して、変更された状態を別のコンテキストでチェックしていますか?多くの場合、このエラーはforeachループで発生し、ループ本体内でそのオブジェクトの新しいインスタンスを割り当てることによって解決されます。 –

+0

@TetsuyaYamamotoいいえ、同じ単一のコンテキスト内にあり、アクセスは基になるDbContextに直接ルーティングされます –

答えて

0

エラーは、トラインだから問題があることを示していますgキーを押して、エンティティのキ​​ー列の一部であるフィールドの状態をIsModifiedに設定します。あなたが見ているエンティティが新しいものではないと確信していますか? CurrentValueOriginalValueと等しい場合でも、IsModifiedはまだtrueであり、変更することはできません。

+0

もう1つのサンプルコードが追加されました。最初のコード例は、2番目の例の変更を取り消そうとしました。 'TenantId'変更トラッカーの変更の更新 –

+0

TenantIdはテーブルのキーの一部ですか? – ErikE

+0

はい、簡単な例で投稿を更新しました –

関連する問題