EF - 区别于IQueryable?

时间:2015-09-16 21:48:10

标签: entity-framework linq-to-entities

说我有这个我希望得到第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抓取和处理数百万个项目来返回唯一值。这会将请求处理时间增加到不可接受的水平。

有没有办法做到这一点?我错过了什么吗?这只是一个简单的例子,显然在一个真实的应用程序中,比字符串更复杂的对象将成为对存储库的查询主题。

3 个答案:

答案 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