2012-02-09 3 views
0

Я работаю над анализатором изменений для Entity Framework и оставил одну небольшую проблему.Entity Framework ObjectStateEntry, получить свойство отношения

Мне нужно получить свойство (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.

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

ответ

0

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

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

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

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 

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

Смежные вопросы