在Linq to Entities中使用自定义方法

3

我在数据库中有一个名为Person的表格,其中包含一个NationalId字段。是否有一种方法可以使用Ef code firstLinq to entities加载所有偶数NationalId的人员,而不必将所有Person加载到内存中?

类似于以下内容:

public  bool IsEven(int number)
{
   return number % 2 == 0;
}

var context = new MyContext();
var personsWithEvenNationalId = context.Persons
                                       .Where(x=> IsEven(x.NationalId))
                                       .ToList();
2个回答

4

您需要在行内进行检查

var personsWithEvenNationalId = context.Persons
                                       .Where(x=> x.NationalId%2 == 0)
                                       .ToList();

Linq to Entities不知道如何将您的自定义方法翻译成SQL。如果您确实需要使用自定义方法,您需要将Persons作为可枚举类型获取,然后使用您的自定义方法,即:

var personsWithEvenNationalId = context.Persons
                                       .AsEnumerable()
                                       .Where(x=> IsEven(x.NationalId))
                                       .ToList();

但这并不是理想的解决方案,因为它将加载所有人员,然后过滤偶数。

编辑:考虑一下,如果您不想每次都编写内联方法,也可以为IQueryable<Person>创建一个扩展方法。可以像这样构建一个Expression

    public static IQueryable<Person> WhereEven(this IQueryable<Person> source, Expression<Func<Person, int>> property)
    {
        var expression = Expression.Equal(
            Expression.Modulo(
                property.Body,
                Expression.Constant(2)),
            Expression.Constant(0));

        var methodCallExpression = Expression.Call(typeof (Queryable),
            "where",
            new Type[] {source.ElementType},
            source.Expression,
            Expression.Lambda<Func<Person, bool>>(expression, property.Parameters));

        return source.Provider.CreateQuery<Person>(methodCallExpression);
    }

并且要使用它:

context.Persons.WhereEven(x => x.NationalId).ToList();

1

与其编写一个能够完成所需功能的函数,您需要拥有一个提供所需投影的Expression的函数(或属性、字段):

public static Expression<Func<int, bool>> IsEven()
{
    return number => number % 2 == 0;
}

您现在可以编写:

using(var context = new MyContext())
{
    var personsWithEvenNationalId = context.Persons
        .Select(x=> x.NationalId)
        .Where(IsEven())
        .ToList();
}

它可以工作,但如果我想选择Person的所有字段而不仅仅是NationalId怎么办? - Masoud
这太棒了!但我恳求您指导我在哪里放置这些方法或道具,以及您如何称呼它们??拜托了 - aradalvand

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接