为什么在linq to实体查询中使用我的C#扩展方法将数据库项加载到内存中,而不是在DB服务器上运行?
我创建了以下简单的扩展方法:为什么在linq to实体查询中使用我的C#扩展方法将数据库项加载到内存中,而不是在DB服务器上运行?,c#,entity-framework,linq-to-entities,extension-methods,C#,Entity Framework,Linq To Entities,Extension Methods,我创建了以下简单的扩展方法: public static IQueryable<TSource> DistinctBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector) { return source.GroupBy(keySelector) .Select(g
public static IQueryable<TSource> DistinctBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
{
return source.GroupBy(keySelector)
.Select(g => g.FirstOrDefault())
.AsQueryable();
}
请注意,此扩展方法只是一个示例。不使用它,而是直接使用方法中定义的代码相对容易。我之所以这么说,是因为我不是在问如何制作一个“DistinctBy”方法。相反,我要问的是如何编写一个只使用其他“可翻译”方法来避免代码重复的扩展方法
我知道我只能使用EF提供者提供的扩展方法,但本质上,这就是我正在做的。我不能让它知道我的方法可以直接转换为SQL吗?
GroupBy
方法是如何实现的?AsQueryable()调用在这里为您提供了什么服务?GroupBy
和FirstOrDefault
返回IEnumerable。为了让扩展方法返回IQueryable,我需要使用它将其转换为IQueryable。我确实尝试过这种扩展方法的几种变体,它们返回IEnumerable等,但它们都表现出相同的行为。除非进行更新,否则数据不会被传输回数据库。linq中的Q表示作为读取的查询。若要在数据库中运行查询,您需要一个存储过程。也许您必须编写keySelector@不,他的键盘选择器是硬编码的,这不是问题所在
// Executes in less than 200ms.
var test_1 = dbContext.SomeTable.GroupBy(row => new { row.SomeColumn, row.SomeOtherColumn })
.Select(g => g.FirstOrDefault())
.Tolist();
// The line below takes some 20 minutes to eventually throw an out of memory exception.
// Notice I'm not even calling ToList().
var test_2 = dbContext.SomeTable.DistinctBy(row => new { row.SomeColumn, row.SomeOtherColumn });