2

在 EF4 中,我的对象图很小,数据量也很小。因此,对于查询,我想急切地加载所有相关数据。是否有任何单个方法调用可以完成这项工作,例如"IQueryable.IncludeEverything()",而不是Include()使用硬编码的属性名称重复调用?

4

1 回答 1

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;
    }

请注意,此代码仅用于说明。它没有参数验证,它可能多次包含相同的实体,并且如果您的模型中有循环,它不会包含所有相关实体。

于 2012-09-19T19:07:47.543 回答