在linq中使用自定义方法实体

时间:2015-05-26 07:40:58

标签: c# entity-framework ef-code-first linq-to-entities

我的数据库中有一个Person表,其中包含NationalId字段。 有没有办法使用NationalIdEf code first加载所有人Linq to entities,而无需将所有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 个答案:

答案 0 :(得分:2)

你必须在线检查

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();

但这并不理想,因为它会加载所有人,然后在IsEven上过滤

编辑:考虑到这一点,如果您不想每次都必须将其内联写入,您还可以为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 :(得分: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();
}