2012-09-18 104 views
2

在EF4中,我有一個小對象地圖,數據量也很小。所以對於我想要加載所有關聯數據的查詢。是否有任何可以完成這項工作的方法調用,如"IQueryable.IncludeEverything()",而不是使用硬編碼的屬性名稱反覆調用Include()實體框架急切加載/「IncludeEverything()」?

回答

4

沒有什麼現成的,但你可以使用MetadataWorkspace實現它:

public static IQueryable<T> IncludeEverything<T>(this IQueryable<T> query, ObjectContext context) 
     where T : class 
    { 
     var ospaceEntityType = context.MetadataWorkspace.GetItem<EntityType>(
      typeof(T).FullName, DataSpace.OSpace); 

     var cspaceEntityType = context.MetadataWorkspace.GetEdmSpaceType(ospaceEntityType); 

     var includedTypes = new HashSet<EdmType>(); 
     includedTypes.Add(cspaceEntityType); 

     return IncludeEverything(query, cspaceEntityType as EntityType, "", includedTypes); 
    } 

    private static IQueryable<T> IncludeEverything<T>(IQueryable<T> query, 
     EntityType entity, 
     string path, 
     HashSet<EdmType> includedTypes) 
     where T : class 
    { 
     foreach (var navigationProperty in entity.NavigationProperties) 
     { 
      var propertyEdmType = navigationProperty.TypeUsage.EdmType; 
      if (includedTypes.Contains(propertyEdmType)) 
      { 
       continue; 
      } 
      includedTypes.Add(propertyEdmType); 

      var propertyCollectionType = propertyEdmType as CollectionType; 

      EntityType propertyEntityType; 
      if (propertyCollectionType != null) 
      { 
       propertyEntityType = propertyCollectionType.TypeUsage.EdmType as EntityType; 
      } else 
      { 
       propertyEntityType = propertyEdmType as EntityType; 
      } 

      var propertyPath = string.IsNullOrEmpty(path) ? "" : path + "."; 
      propertyPath += navigationProperty.Name; 
      query = query.Include(propertyPath); 
      query = IncludeEverything(query, propertyEntityType, propertyPath, includedTypes); 
     } 

     return query; 
    } 

請注意,此代碼只是爲了說明。它沒有參數驗證,它可能包含幾次相同的實體,並且如果模型中存在循環,它將不包含所有相關實體。

+0

謝謝,不知道MetadataWorkspace,真的很有用! –