LINQ到实体自定义的方法
问题描述:
在我的代码有:LINQ到实体自定义的方法
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到实体不识别方法 '布尔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 SQL使用“Expression Trees”将lambda表达式转换为sql表达式。所以你不能使用方法,只能使用内联表达式。但是你可以在Linq中使用方法来集合。如果您在TableA
上先拨打.ToList()
功能,则可以调用方法。但.ToList()
函数将首先检索内存中的所有内容,然后对其进行过滤。所以这是非常不推荐的。
+0
这不是一个选项,我宁愿去解决方案2 – Medo
答
尝试使用表达式
表达式定义
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));
可惜没有办法在Linq to Entities中使用扩展方法,因为EF不支持此功能。 – Vladimir
我想你可以使用'bool RecordExists(这个IEnumerable 实体,...'而不是;)。 –
@ shA.t为什么会这样? – Medo