首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在带有Linq到实体框架的表达式中使用Func?

如何在带有Linq到实体框架的表达式中使用Func?
EN

Stack Overflow用户
提问于 2013-09-27 13:50:15
回答 1查看 16.6K关注 0票数 9

我正在尝试编写一个linq到实体扩展方法,该方法使用Func来选择属性Id,并将其与Id列表进行比较。

代码语言:javascript
运行
复制
public class A
{
    public int AId { get; set; }
}

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

可拓方法

代码语言:javascript
运行
复制
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)
    }

调用方法

代码语言:javascript
运行
复制
var ids = new List<int> { 1, 2, 3 };
DbContext.EntityAs.WithId(e => e.AId, ids);
DbContext.EntityBs.WithId(e => e.BId, ids);

我遇到的问题是,它试图调用实体框架中不允许的函数。

如何使用属性选择器(Func)计算查询?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-09-27 14:30:28

您必须传递一个Expression<Func<T, int>>而不是一个Func<T, int>,并自己构建完整的表达式。这将起到以下作用:

代码语言:javascript
运行
复制
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);
}

当您在使用O/RM时试图使代码保持干燥时,您通常需要修改表达式树。这是another fun example

票数 20
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19052507

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档