EF4 LINQ Include(string) alternative to hard-coded

2020-02-23 07:58发布

Is there any alternative to this:

Organizations.Include("Assets").Where(o => o.Id == id).Single()

I would like to see something like:

Organizations.Include(o => o.Assets).Where(o => o.Id == id).Single()

to avoid the hard-coded string "Assets".

7条回答
疯言疯语
2楼-- · 2020-02-23 08:45

That's pretty easy to do, using Expressions :

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

You can use it exactly as in the example in your question


UPDATE

Improved version, which supports multiple chained properties :

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

Example :

var query = X.Include(x => x.Foo.Bar.Baz) // equivalent to X.Include("Foo.Bar.Baz")
查看更多
登录 后发表回答