2012-02-15 5 views
0

Я использую динамический способ включения «родительских свойств», когда я извлекаю объекты из db. Однако, поскольку это проверяет, является ли свойство типом значения (или строкой) или ienumerable чего-либо (за исключением тех), он также будет включать объекты, которые определены как типы комплексов. Это приведет к исключению.Entity Framework 4.3 POCO Include on Complex Types throws exception

Можно ли проверить, был ли объект определен как сложный тип?

Пожалуйста, смотрите этот пример кода:

public IEnumerable<object> LookupExtent(Type type) 
{ 
     var set = Set(type); 

     DbQuery q = null; 

     foreach (var prop in type.GetParentProperties()) 
     { 
      if (q == null) 
       q = set.Include(prop.Name); 
      else 
       q = q.Include(prop.Name); 
     } 

     return q.ToObjectArray(); 
    } 

PS: Да я знаю, что это не сработает, если у меня нет родительских свойств ...

ответ

1

Он имеет гораздо больше проблем. Что произойдет, если ваша сущность содержит некоторые дополнительные неработающие свойства? Вы можете попросить EF дать вам имена всех отображаемых навигационных свойств. Для получения информации из метаданных EF мало науки, но это возможно. Попробуйте что-то вроде этого (код ожидает, что вы используете DbContext API, но он может быть легко изменен на ObjectContext API):

ObjectContext objectContext = ((IObjectContextAdapter) dbContext).ObjectContext; 
MetadataWorkspace workspace = objectContext.MetadataWorkspace; 
EntityContainer container = 
    workspace.GetEntityContainer("NameOfYourContextClass", true, DataSpace.CSpace); 
EntitySet entitySet = 
    container.GetEntitySetByName("NameOfYourPropertyExposingDbSetOnTheContext", true); 
IEnumerable<string> navigationPropertyNames = 
    entitySet.ElementType.NavigationProperties.Select(n => n.ToString()); 

Ключ обеспечивает правильные имена в GetEntityContainer и GetEntitySetByName и это также основное различие между сначала код и db/model. Если вы используете код сначала, эти имена следует за некоторыми соглашениями. Если вы используете EDMX, вы можете управлять этими именами в дизайнере.

В любом случае этот автомат Include - это то, что вам следует избегать использовать. Включите только данные, которые вам действительно нужны, и делайте это явно, чтобы всегда показывать complexity of the query.

+0

Я понимаю ваши проблемы и то, что я пытаюсь достичь, не является «случаем использования по умолчанию». Я буду использовать этот автомат только в особых случаях. Случай по умолчанию не включает никаких родительских или дочерних свойств, и загрузка этих данных должна быть явно указана. Я дам ваш код попробовать и пометить ваш ответ, когда вернусь в офис (в следующий понедельник), поэтому вам придется немного подождать ;-) – UrbanEsc