Entity Framework жаждет загрузки/ " IncludeEverything ()"?


В EF4 у меня есть небольшая карта объектов, и объем данных также невелик. Поэтому для запросов я хочу быстро загрузить все связанные данные. Существует ли какой-либо один вызов метода, который может выполнить эту работу, например "IQueryable.IncludeEverything()", а не вызывать Include() повторно с жестко заданными именами свойств?

1 2

1 ответ:

Там нет ничего из коробки, но вы можете использовать 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;
    }
Обратите внимание, что этот код-только для иллюстрации. Он не имеет проверки параметров, он может включать одни и те же объекты несколько раз, и он не будет включать все связанные объекты, если в вашей модели есть циклы.