C# IQueryable<;T>;给出与列表不同的结果<;T>;
如果我在实体框架结果中使用Select on IQueryable,我将得到4项结果 如果我在IQueryable.ToList()上使用Select,我将获得所有36项 下面是函数的代码:C# IQueryable<;T>;给出与列表不同的结果<;T>;,c#,linq,entity-framework,C#,Linq,Entity Framework,如果我在实体框架结果中使用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 = ImageHandl
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);
}
公共图像GetModelView获取(int开始,int计数)
{
如果(count ImageHandler.MaxResult)count=ImageHandler.MaxResult;
IQueryable imagesList=ImagesHandler.FetchRangeScore(开始,计数)
.Where(m=>m.Domain==Database.Enums.ImageDomain.Gfycat);
//作品使用清单:(
//var list=imagesList.ToList();
//选择所有子项一次
//如果不使用列表,则返回4而不是36。。。
//如果不使用列表,则返回1,而不是带有Distinct()的2
IEnumerable subreddits=图像列表
.Select(m=>m.Subreddit);//.Distinct();
ImagesGetModelView结果=新建ImagesGetModelView()
{
项目=图像列表,
Subreddits=Subreddits
};
返回结果;
}
公共IQueryable FetchRangeScore(整数开始,整数计数)
{
返回Repository.AllQueryable().OrderByDescending(m=>m.Score)
.跳过(开始)。进行(计数);
}
在36项中,有2个子项是不同的。但由于36项中只有4项是从Select()获取的,所以它只找到1个不同的子项
那么,我可以用LINQ表达式做些什么来获得正确的数据,从而使distinct语句工作,还是在继续使用Select&distinct函数之前必须将其放入列表中
编辑:通过将where语句从整个查询的末尾移动到开头。 它现在似乎工作正常。Select返回所有36项e.t.c.。这反过来又使不同的工作正常,因为它可以找到多个唯一值
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);
}
public IQueryable FetchRangeScore(整数开始,整数计数)
{
return Repository.AllQueryable()
.Where(m=>m.Domain==Database.Enums.ImageDomain.Gfycat)
.OrderByDescending(m=>m.Score)
.跳过(开始)。进行(计数);
}
没有源数据很难确定,但是Distinct
在推送到SQL时的工作方式不同
SQLDISTINCT
查询将提取所有值都不同的记录。当您对内存中的对象列表执行DISTINCT
调用时,默认情况下它将使用实例相等。因此,您可以返回“重复”对象(所有字段值相同的对象),但它们将是不同的“实例”,因此Distinct
将它们视为不同的对象
因此,这取决于您想要什么-您想要所有的Subreddit
值,包括重复的值,还是想要不同的值
回答您的问题-如果您不想将
Distinct
调用传递给SQL,您可以调用AsEnumerable()
而不是ToList
,这使得所有进一步的Linq查询Linq To对象(IEnumerable
)查询而不是Linq To-{where}(IQueryable
)查询,而无需将项目放入列表中的开销。很可能您的Where
子句在SQL Server中的行为与在.NET中的行为不同。具体而言,根据排序规则设置等,各种.Domain
值可能仅因大小写或类似内容而不同,这使得hem在SQL中与Gfycat“相等”,但在C#中不相等
您可以在您的IQueryable
上捕获.ToString()
,以查看正在生成的SQL并自己尝试
IQueryable<Image> imagesList = ImagesHandler.FetchRangeScore(start, count)
.Where(m => m.Domain == Database.Enums.ImageDomain.Gfycat);
Debug.WriteLine(imagesList.ToString());
IQueryable imagesList=ImagesHandler.FetchRangeScore(开始,计数)
.Where(m=>m.Domain==Database.Enums.ImageDomain.Gfycat);
Debug.WriteLine(imagesList.ToString());
一些模拟数据可能有助于说明您的观点。我建议将您的逻辑放在不同的版本(或您更改的第二个代码片段)中。在需要更改的代码中很难找到注释(例如,我无法判断您的示例是否已损坏或工作正常).在调用distinct之前进行分页有什么原因吗?我通常会期望相反的顺序。我只想要不同的值,而不是重复的值。我需要将子Reddit清楚地分隔以获得结果。我相信你是正确的。你让我意识到我在那里有一个where语句:)我很久以前添加它是为了测试,后来对它视而不见。当你看它的时候,它的位置很好,但是数据集是36种类型中的35种,所以直到昨晚我才注意到它是错误的。当我把它移到查询的开头时,我注意到Debug.WriteLine()不再返回子查询,而且似乎一切都正常。