У меня проблема с переносом дочерних объектов от одного родителя к другому из-за того, что дочерний объект имеет составной первичный ключ, который также является частью внешнего ключа.
Технически говоря, это та же проблема, что и Entity Framework: Отменить изменение свойства, если значение не изменилось
Но с того 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 и устраняется путем назначения нового экземпляра этого объекта внутри тела цикла. - person Tetsuya Yamamoto   schedule 21.04.2017