エンティティの子にも複合キーがあり、外部キーの一部であるため、子エンティティをある親から別の親に転送する際に問題がありますプロパティ値が等しい場合に値が変更されないように設定する
技術的には 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;
}
}
同じ「ChangeTracker」オブジェクトを2回以上参照して、変更された状態を別のコンテキストでチェックしていますか?多くの場合、このエラーはforeachループで発生し、ループ本体内でそのオブジェクトの新しいインスタンスを割り当てることによって解決されます。 –
@TetsuyaYamamotoいいえ、同じ単一のコンテキスト内にあり、アクセスは基になるDbContextに直接ルーティングされます –