如果我在我的实体框架结果上使用Select on IQueryable,我将得到4个项目。
如果我在IQueryable.ToList()上使用Select,我会得到所有36项。
这是函数的代码:
public ImagesGetModelView Get(int start, int count)
{
if (count <= 0) count = 9;
else if (count > ImageHandler.MaxResult) count = ImageHandler.MaxResult;
IQueryable<Image> imagesList = ImagesHandler.FetchRangeScore(start, count)
.Where(m => m.Domain == Database.Enums.ImageDomain.Gfycat);
//Works using list :(
//var list = imagesList.ToList();
//Select all subreddits once
//Returns 4 instead of 36 if not using the list ...
//Returns 1 instead of 2 with Distinct() if not using the list
IEnumerable<Subreddit> subreddits = imagesList
.Select(m => m.Subreddit); //.Distinct();
ImagesGetModelView result = new ImagesGetModelView()
{
Items = imagesList,
Subreddits = subreddits
};
return result;
}
public IQueryable<Image> FetchRangeScore(int a_start, int a_count)
{
return Repository.AllQueryable().OrderByDescending(m => m.Score)
.Skip(a_start).Take(a_count);
}
36项中的2项Subreddits将是截然不同的。但由于从Select()中只取出了36个中的4个,因此只能找到1个不同的。
所以我可以使用LINQ表达式来获取正确的数据,以便使用distinct语句,或者在继续使用Select&amp; amp;之前我必须将它变成List。不同的功能?
编辑:
通过将where satement从结尾移动到整个查询的开头。
它似乎现在正常工作。选择返回所有36项e.t.c ...这反过来使得Distinct工作,因为它可以找到多于1个唯一值。
public IQueryable<Image> FetchRangeScore(int a_start, int a_count)
{
return Repository.AllQueryable()
.Where(m => m.Domain == Database.Enums.ImageDomain.Gfycat)
.OrderByDescending(m => m.Score)
.Skip(a_start).Take(a_count);
}
答案 0 :(得分:5)
如果没有源数据,很难确定,但Distinct
在推送到SQL时的工作方式不同。
SQL DISTINCT
查询将提取所有值不同的记录。当您对内存中的对象列表执行Distinct
调用时,默认情况下它将使用 instance 相等。所以你可能会回来&#34;重复&#34;对象(所有字段值相同的对象),但它们将是不同的&#34;实例&#34;,因此Distinct
将它们视为不同的对象。
所以这取决于你想要什么 - 你想要所有Subreddit
值包括重复还是你想要不同的值?
要回答您的问题 - 如果您不希望将Distinct
调用传递给SQL,则可以调用AsEnumerable()
而不是ToList
,这会使所有进一步的Linq查询Linq-to-Objects(IEnumerable<T>
)查询而不是Linq-to- {whatever}(IQueryable<T>
)查询,而没有将项目放在列表中的开销。
答案 1 :(得分:5)
最有可能的是,Where
子句在SQL Server中的行为与在.NET中的行为不同。具体来说,根据您的归类设置等,各种.Domain
值可能只有大小写或类似的差异,使它们与SQL中的Gfycat“相等”,而不是在C#中。
您可以捕获.ToString()
上的IQueryable<>
以查看正在生成的SQL并自行尝试。
IQueryable<Image> imagesList = ImagesHandler.FetchRangeScore(start, count)
.Where(m => m.Domain == Database.Enums.ImageDomain.Gfycat);
Debug.WriteLine(imagesList.ToString());