如果属性值相等,则将值设置为未修改

时间:2017-04-21 00:56:53

标签: c# entity-framework entity-framework-6 composite-key change-tracking

由于实体子项具有复合主键,而且也是外键的一部分,因此我将子实体从一个父项转移到另一个父项时遇到问题

从技术上讲,它的问题与此相同 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; 
    }
}

1 个答案:

答案 0 :(得分:0)

该错误告诉您该问题是因为您尝试设置字段的IsModified状态,该字段是实体的关键列的一部分。您确定您正在查看的实体不是新实体吗?这可能是CurrentValue等于OriginalValue的情况,但IsModified仍然是真的,无法更改。