Я работаю над анализатором изменений для Entity Framework и у меня осталась одна небольшая проблема.
Мне нужно получить Свойство (PropertyInfo
) родителя в отношении (1-1, 1-n, n-n).
Прямо сейчас я могу видеть отношение, родитель и связанные записи, но я не могу получить фактическое свойство объекта. Проблема, как я вижу, состоит в том, что отношение знает о ключах, которые являются PK и FK, а не тем свойством, которое отвечало за отношение в первую очередь. В своем решении сейчас я использую имя EntitySet из связанной сущности, но этого недостаточно.
Вот код, который разрешает отношения. Я исключил объекты сущностей, а также нереляционные части анализа. Интерфейс IHaveLogEntries
должен быть реализован на объектах, которые необходимо проанализировать.
Кроме того, этот код работает в DbContext.SaveChanges()
this.ChangeTracker.DetectChanges();
var objectContext = ((IObjectContextAdapter)this).ObjectContext;
var entityEntries = objectContext.ObjectStateManager
.GetObjectStateEntries(EntityState.Unchanged | EntityState.Modified | EntityState.Added)
.ToList();
var relationEntries = objectContext.ObjectStateManager
.GetObjectStateEntries(EntityState.Added | EntityState.Deleted)
.ToList();
var q = from relationEntry in relationEntries
from entityEntry in entityEntries
where relationEntry.IsRelationshipForKey(entityEntry.EntityKey)
where !(entityEntry.Entity is IHaveLogEntries)
let otherEndKey = relationEntry.OtherEndKey(entityEntry.EntityKey)
let logEntryEntity = entityEntries
.Where(e => e.EntityKey == otherEndKey)
.Select(se => se.Entity)
.Cast<IHaveLogEntries>()
.Single()
let combined = new
{
RelationEntry = relationEntry,
EntityEntry = entityEntry,
LogEntryEntity = logEntryEntity
}
group combined by
new { combined.LogEntryEntity, combined.EntityEntry.EntitySet.Name }
into combinedGroup
let added = combinedGroup
.Where(c => c.RelationEntry.State == EntityState.Added)
.Select(c => c.EntityEntry.Entity.ToString())
let deleted = combinedGroup
.Where(c => c.RelationEntry.State == EntityState.Deleted)
.Select(c => c.EntityEntry.Entity.ToString())
select new
{
combinedGroup.Key.LogEntryEntity,
Field = combinedGroup.Key.Name,
Operation = Operation.Modified,
FromValue = (object)string.Join(",", deleted.ToArray()),
ToValue = (object)string.Join(",", added.ToArray())
};
var l = q.ToList();
Основная проблема в том, где я группирую результат, где я использую combined.EntityEntry.EntitySet.Name
. Вместо этого я хотел бы выяснить имя свойства объекта IHaveLogEntries
, если это возможно. В этом случае эта сущность будет combined.LogEntryEntity
.
Благодарен за ваш вклад.