【发布时间】:2017-04-21 00:56:53
【问题描述】:
我在将子实体从一个父实体转移到另一个父实体时遇到问题,因为实体子实体有一个复合主键,它也是外键的一部分
从技术上讲,它的问题与 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;
}
}
【问题讨论】:
-
您是否不小心多次引用相同的
ChangeTracker对象来检查修改状态(通过不同的上下文)?此错误通常发生在 foreach 循环中,并通过在循环体中分配该对象的新实例来解决。 -
@TetsuyaYamamoto 不,它都在同一个上下文中,访问直接路由到底层 DbContext
标签: c# entity-framework entity-framework-6 composite-key change-tracking