如何在一个表达式中使用Func与Linq到实体框架? [英] How to use a Func in an expression with Linq to Entity Framework?

查看:116
本文介绍了如何在一个表达式中使用Func与Linq到实体框架?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我正在尝试将一个linq写入实体扩展方法,该方法需要一个Func才能选择一个属性ID,并将其与ids列表进行比较。课程

  public class A 
{
public int AId {get;组; }
}

public class B
{
public int BId {get;组; }
}

扩展方法

  public static IQueryable< T> WithId< T>(这个IQueryable< T>实体,
Func< T,int>选择器,IList< int> ids)
{
表达式< Func< T,bool> expression = x => ids.Contains(选择器(X));
return entities.Where(expression); // error here(when evaluate)
}

调用方法

  var ids = new List< int> {1,2,3}; 
DbContext.EntityAs.WithId(e => e.AId,ids);
DbContext.EntityBs.WithId(e => e.BId,ids);

我遇到的问题是它试图调用Entity Framework中不允许的函数



如何使用属性选择器(Func)来评估查询?

解决方案

你必须传递一个表达式< Func< T,int>> 而不是 Func< T,int& ; 并自己建立完整的表达。这将是诀窍:

  public static IQueryable< T> WithId< T>(此IQueryable< T>实体,
表达式< Func< T,int>> propertySelector,ICollection< int> ids)
{
var property =
(的PropertyInfo)((MemberExpression)propertySelector.Body)。成员;

ParameterExpression parameter = Expression.Parameter(typeof(T));

var expression = Expression.Lambda< Func< T,bool>>(
Expression.Call(
Expression.Constant(ids),
typeof(ICollection< ; int>)。GetMethod(Contains),
Expression.Property(parameter,property)),
参数);

return entities.Where(expression);
}

当您尝试使用O / RM时,你经常不得不嘲笑表情树。以下是另一个有趣的示例


I am trying to write a linq to entity extension method that takes a Func to select a property Id and compare it against a list of ids.

Classes

public class A
{
    public int AId { get; set; }
}

public class B
{
    public int BId { get; set; }
}

Extension Method

public static IQueryable<T> WithId<T>(this IQueryable<T> entities,
    Func<T, int> selector, IList<int> ids)
    {
        Expression<Func<T, bool>> expression = x => ids.Contains(selector(x));
        return entities.Where(expression); // error here (when evaluated)
    }

Calling Method

var ids = new List<int> { 1, 2, 3 };
DbContext.EntityAs.WithId(e => e.AId, ids);
DbContext.EntityBs.WithId(e => e.BId, ids);

The problem I am experiencing is that it is trying to Invoke the function which is not allowed in Entity Framework.

How can I use a property selector (Func) to evaluate the query?

解决方案

You'll have to pass an Expression<Func<T, int>> instead of an Func<T, int> and build up the complete expression yourself. This will do the trick:

public static IQueryable<T> WithId<T>(this IQueryable<T> entities,
    Expression<Func<T, int>> propertySelector, ICollection<int> ids)
{
    var property =
        (PropertyInfo)((MemberExpression)propertySelector.Body).Member;

    ParameterExpression parameter = Expression.Parameter(typeof(T));

    var expression = Expression.Lambda<Func<T, bool>>(
        Expression.Call(
            Expression.Constant(ids),
            typeof(ICollection<int>).GetMethod("Contains"), 
            Expression.Property(parameter, property)), 
        parameter);

    return entities.Where(expression);
}

When you try to keep your code DRY when working with your O/RM, you will often have to fiddle with expression trees. Here's another fun example.

这篇关于如何在一个表达式中使用Func与Linq到实体框架?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆