说我有这个我希望得到第42组中的每个人,但我希望获得数据库中每个唯一名字的IQueryable(PS - 我知道我可以在Select之后调用AsQueryable()但不是我有兴趣做什么 - 我希望数据库执行不同的,而不是程序):
MyEfContextContainer db = new MyEfContextContainer();
IQueryable<string> uniqueFirstNames =
db.People
.Where(x=> x.GroupId == 42)
.DistinctBy(c=> c.FirstName)
.Select(c=> c.FirstName);
从我所知道的EF / LINQ to Entities如何处理DistinctBy扩展方法,调用DistinctBy时执行存储查询,并且数据库中与Where匹配的所有项目列表被检索,然后C#返回IEnumberable来自与发送到DistinctBy的表达式匹配的DistinctBy方法。
如果列表中有数百万个名字,效率非常低。
我感兴趣的是能够有效地执行此操作,希望通过使商店查询仅返回表中所有唯一FirstNames的结果集。例如,我可能希望将IQueryable作为存储库的一部分返回,因为性能原因不能通过DistinctBy抓取和处理数百万个项目来返回唯一值。这会将请求处理时间增加到不可接受的水平。
有没有办法做到这一点?我错过了什么吗?这只是一个简单的例子,显然在一个真实的应用程序中,比字符串更复杂的对象将成为对存储库的查询主题。
答案 0 :(得分:9)
我写了这个扩展名:
@task
def send_emails(messages):
mailserver.sendMultipleMessages(messages)
根据属性进行不同的选择,例如对,我只是打电话:
public static IQueryable<TSource> DistinctBy<TSource, TKey> (this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
{
return source.GroupBy(keySelector).Select(x => x.FirstOrDefault());
}
答案 1 :(得分:7)
使用IQueryable
,您必须自己完成:
db.People
.Where(x => x.GroupId == 42)
.GroupBy(c => c.FirstName)
.Select(g => g.FirstOrDefault());
MoreLinq的DistinctBy
方法是IEnumerable<T>
上的扩展方法,因此它接受IQueryable<T>
,但在方法中它充当IEnumerable<T>
。这与执行db.People.AsEnumerable().DistinctBy()
答案 2 :(得分:-1)
从你的 NuGet 包管理器安装 morelinq,你将能够使用 DistinctBy 和 IQueryable