EF4 LINQ Включить (строку) альтернативу жестко закодированной строке?

Ответ @aaronheckmann работал для меня, но мне пришлось заменить return doc.tags.length; на return doc.tags != null;, потому что это поле содержит null, если оно не совпадает с условиями, записанными внутри заполнения. Итак, окончательный код:

query....
.exec(function(err, docs){
   docs = docs.filter(function(doc){
     return doc.tags != null;
   })
   // do stuff with docs
});

13
задан Craig Stuntz 6 April 2010 в 16:21
поделиться

3 ответа

Для Entity Framework 1.0 я создал несколько методов расширения для этого.

public static class EntityFrameworkIncludeExtension
{
    public static ObjectQuery<T> Include<T>(this ObjectQuery<T> src, Expression<Func<T, StructuralObject>> fetch)
    {
        return src.Include(CreateFetchingStrategyDescription(fetch));
    }

    public static ObjectQuery<T> Include<T>(this ObjectQuery<T> src, Expression<Func<T, RelatedEnd>> fetch)
    {
        return src.Include(CreateFetchingStrategyDescription(fetch));
    }

    public static ObjectQuery<T> Include<T, TFectchedCollection>(this ObjectQuery<T> src, Expression<Func<T, IEnumerable<TFectchedCollection>>> fetch)
    {
        return src.Include(CreateFetchingStrategyDescription(fetch));
    }

    public static ObjectQuery<T> Include<T, FetchedChild>(this ObjectQuery<T> src, Expression<Func<T, RelatedEnd>> fetch, Expression<Func<FetchedChild, Object>> secondFetch)
        where FetchedChild : StructuralObject
    {
        return src.Include(CombineFetchingStrategies(fetch, secondFetch));
    }

    public static ObjectQuery<T> Include<T, FetchedChild>(this ObjectQuery<T> src, Expression<Func<T, RelatedEnd>> fetch, Expression<Func<FetchedChild, RelatedEnd>> secondFetch)
        where FetchedChild : StructuralObject
    {
        return src.Include(CombineFetchingStrategies(fetch, secondFetch));
    }

    public static ObjectQuery<T> Include<T, FetchedChild>(this ObjectQuery<T> src, Expression<Func<T, RelatedEnd>> fetch, Expression<Func<FetchedChild, StructuralObject>> secondFetch)
        where FetchedChild : StructuralObject
    {
        return src.Include(CombineFetchingStrategies(fetch, secondFetch));
    }

    public static ObjectQuery<T> Include<T, FetchedChild>(this ObjectQuery<T> src, Expression<Func<T, IEnumerable<FetchedChild>>> fetch, Expression<Func<FetchedChild, Object>> secondFetch)
        where FetchedChild : StructuralObject
    {
        return src.Include(CombineFetchingStrategies(fetch, secondFetch));
    }

    public static ObjectQuery<T> Include<T, FetchedChild>(this ObjectQuery<T> src, Expression<Func<T, IEnumerable<FetchedChild>>> fetch, Expression<Func<FetchedChild, RelatedEnd>> secondFetch)
        where FetchedChild : StructuralObject
    {
        return src.Include(CombineFetchingStrategies(fetch, secondFetch));
    }

    public static ObjectQuery<T> Include<T, FetchedChild>(this ObjectQuery<T> src, Expression<Func<T, IEnumerable<FetchedChild>>> fetch, Expression<Func<FetchedChild, StructuralObject>> secondFetch)
        where FetchedChild : StructuralObject
    {
        return src.Include(CombineFetchingStrategies(fetch, secondFetch));
    }

    private static String CreateFetchingStrategyDescription<TFetchEntity, TFetchResult>(
        Expression<Func<TFetchEntity, TFetchResult>> fetch)
    {
        fetch = (Expression<Func<TFetchEntity, TFetchResult>>)FixedWrappedMemberAcces.ForExpression(fetch);
        if (fetch.Parameters.Count > 1)
            throw new ArgumentException("CreateFetchingStrategyDescription support only " +
                "one parameter in a dynamic expression!");

        int dot = fetch.Body.ToString().IndexOf(".") + 1;
        return fetch.Body.ToString().Remove(0, dot);
    }

    private static String CreateFetchingStrategyDescription<T>(Expression<Func<T, Object>> fetch)
    {
        return CreateFetchingStrategyDescription<T, Object>(fetch);
    }

    private static String CombineFetchingStrategies<T, TFetchedEntity>(
                Expression<Func<T, Object>> fetch, Expression<Func<TFetchedEntity, Object>> secondFetch)
    {
        return CombineFetchingStrategies<T, Object, TFetchedEntity, Object>(fetch, secondFetch);
    }

    private static String CombineFetchingStrategies<TFetchEntity, TFetchResult, TFetchedEntity, TSecondFetchResult>(
        Expression<Func<TFetchEntity, TFetchResult>> fetch, Expression<Func<TFetchedEntity, TSecondFetchResult>> secondFetch)
    {
        return CreateFetchingStrategyDescription<TFetchEntity, TFetchResult>(fetch) + "." +
            CreateFetchingStrategyDescription<TFetchedEntity, TSecondFetchResult>(secondFetch);
    }
}

Использование:

 Orders.Include(o => o.Product); // generates .Include("Product")
 Orders.Include(o => o.Product.Category); // generates .Include("Product.Category")
 Orders.Include(o => o.History); // a 1-* reference => .Include("History")
 // fetch all the orders, and in the orders collection.
 // also include the user reference so: .Include("History.User")
 // but because history is an collection you cant write o => o.History.User, 
 // there is an overload which accepts a second parameter to describe the fetching 
 // inside the collection.
 Orders.Include(o => o.History, h => h.User); 

Я не тестировал это на EF4.0, но надеюсь, что это сработает.

10
ответ дан 1 December 2019 в 19:30
поделиться

Это довольно просто сделать, используя Выражения:

public static class ObjectQueryExtensions
{
    public static ObjectQuery<T> Include<T, TProperty>(this ObjectQuery<T> objectQuery, Expression<Func<T, TProperty>> selector)
    {
        MemberExpression memberExpr = selector.Body as MemberExpression;
        if (memberExpr != null)
        {
            return objectQuery.Include(memberExpr.Member.Name);
        }
        throw new ArgumentException("The expression must be a MemberExpression", "selector");
    }
}

Вы можете использовать это точно так же, как в примере в вашем вопросе


ОБНОВЛЕНИЕ

Улучшенная версия, которая поддерживает несколько связанных свойств:

public static class ObjectQueryExtensions
{
    public static ObjectQuery<T> Include<T, TProperty>(this ObjectQuery<T> objectQuery, Expression<Func<T, TProperty>> selector)
    {
        string propertyPath = GetPropertyPath(selector);
        return objectQuery.Include(propertyPath);
    }

    public static string GetPropertyPath<T, TProperty>(Expression<Func<T, TProperty>> selector)
    {
        StringBuilder sb = new StringBuilder();
        MemberExpression memberExpr = selector.Body as MemberExpression;
        while (memberExpr != null)
        {
            string name = memberExpr.Member.Name;
            if (sb.Length > 0)
                name = name + ".";
            sb.Insert(0, name);
            if (memberExpr.Expression is ParameterExpression)
                return sb.ToString();
            memberExpr = memberExpr.Expression as MemberExpression;
        }
        throw new ArgumentException("The expression must be a MemberExpression", "selector");
    }
}

Пример:

var query = X.Include(x => x.Foo.Bar.Baz) // equivalent to X.Include("Foo.Bar.Baz")
8
ответ дан 1 December 2019 в 19:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: