Entity Framework ObjectStateEntry, получить свойство отношения - PullRequest
0 голосов
/ 09 февраля 2012

Я работаю над анализатором изменений для 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.

Благодарен за ваш вклад.

1 Ответ

0 голосов
/ 10 февраля 2012

Я решил это сейчас, используя свойство ObjectStateEntry.EntitySet относительного входа, которое у меня было. После этого я могу увидеть имя отношения как это Entity_Property , и я просто выполняю извлечение строки имени свойства, которое я затем использую, чтобы получить объект PropertyInfo из Entity .

Затем я добавил am Attribute, чтобы при необходимости я мог украсить свойства более подходящими именами.

Это то, что я добавил где-то посередине:

let propertyName = relationEntry
    .EntitySet
    .Name
    .Split("_".ToCharArray())
    .Last()
let property = logEntryEntity
    .GetType()
    .GetProperty(propertyName)
let nameAttribute = property
   .GetCustomAttributes(typeof(NameAttribute), true)
   .Cast<NameAttribute>()
   .FirstOrDefault()
let name = nameAttribute != null ? nameAttribute.Name : property.Name

Затем я использую имя для группировки вместо:

let combined = new {
   FieldName = name,
   RelationEntry = relationEntry,
   EtityEntry = entityEntry,
   LogEntryEntity = logEntryEntity
}
group combined by new { combined.LogEntryEntity, combined.FieldName } 
   into combinedGroup

Кажется, до сих пор это работает, хотя я хотел бы знать, есть ли у кого-нибудь идея получше. Управление струнами кажется немного хитрым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...