LINQ to Entities自定义方法

3

我的代码中有:

context.TableA
            .Where(x =>
                x.Created >= startDate
                && context.TableB.RecordExists(x.Id, 1));

而RecordExists的定义如下:

public static bool RecordExists(this IQueryable<TableB> entity, int entityId, int entityTypeId)
{
    return entity.Any(x => x.EntityId == entityId && x.EntityTypeId == entityTypeId);
}

上述调用失败,出现以下异常:

NotSupportedException: LINQ to Entities 不识别方法 'Boolean RecordExists(System.Linq.IQueryable`1[TableB], Int32, Int32)',且该方法无法转换为存储表达式。

但如果我将查询语句更改为:

 context.TableA
            .Where(x =>
                x.Created >= startDate
                && context.TableB.Any(p => p.EntityId == x.Id && p.EntityTypeId == 1));

这个方法运行正常,有没有一种方法可以在查询中使用它?


不幸的是,在Linq to Entities中没有办法使用扩展方法,因为EF不支持此功能。 - Vladimir
我认为你可以使用 bool RecordExists<T>(this IEnumerable<T> entity, ... 代替 ;). - shA.t
@shA.t 为什么会有效? - Medo
我并不是说这一定会奏效!我是说你可以完全使用一个通用的形式;)。 - shA.t
2个回答

4

Try to use Expressions

Expression definition

public Expression<Func<TableA, bool>> RecordExists(IEnumerable<TableB> entities, int entityTypeId)
{
    return a => entities.Any(b => b.Id == a.EntityId && b.EntityTypeId == entityTypeId);
}

例子

return context.TableA
    .Where(x => x.Created >= startDate)
    .Where(RecordExists(context.TableB, 1));

Entity Framework 过滤器


1
Linq to SQL使用“表达式树”将lambda表达式转换为sql表达式。因此,您不能使用方法,只能使用内联表达式。但是,在Linq到集合中可以使用方法。如果您首先在TableA上调用.ToList()函数,那么就可以调用方法。但是,.ToList()函数会首先检索所有内容并进行过滤。因此,这是非常不推荐的。

1
那不是一个选项,我宁愿选择方案2。 - Medo

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