我们有一个简单的LINQ-to-Entities查询,它应该从特定页面返回特定数量的元素.请求的示例可以是:
var query = from r in records
orderby r.createdDate descending
select new MyObject()
{ ... };
//Parameters: pageId = 8, countPerPage = 10
List<MyObject> list = query.Skip(pageId * countPerPage).Take(countPerPage);
Run Code Online (Sandbox Code Playgroud)
上面的示例在大多数情况下都很有效,但有时候列表中有10个以上的元素.这似乎并不总是正确的,取决于数据库数据.例如,当我们请求页面10并将countPerPage作为10时,我们得到10个元素.但是当我们请求页面12并将countPerPage传递为10时,我们得到了11个元素.然后,当我们要求第21页时,我们再次获得10个元素.
这有什么可能的原因吗?
更新:查询,当然,并不像在示例中那么简单,并包含子查询.
这是一个更完整的例子:
var elementsQuery = from m in entityContext.elements
where m.elementSearchText.Contains(filter)
orderby m.CreatedDate descending
select new DataContracts.ElementForWeb()
{
FirstName = m.FirstName,
LastName = m.LastName,
Photos = (from p in m.Photos select p.ID),
PlacesCount = m.Childs.Where(x => x.Place != null).Count() + ((m.MainChild != null)?1:0),
SubElements = (
from t in m.Childs
orderby t.CreatedDate descending
select new DataContracts.ChildForWeb()
{
CommentsCount = t.ChildComments.Count,
Photos = (from p in t.Photos select p.ID),
Comments = (from c in t.ChildComments
orderby c.CreatedDate descending
select new DataContracts.CommentForWeb()
{
CommentId = c.ID,
CommentText = c.CommentText,
CreatedByPhotoId = c.Account.UserPhoto,
CreatedDate = c.CreatedDate,
}).Take(5)
}).Take(5)
};
List<DataContracts.ElementForWeb> elements =
new List<DataContracts.ElementForWeb>(
elementsQuery
.Skip(pageId * countPerPage)
.Take(countPerPage));
Run Code Online (Sandbox Code Playgroud)
更新2:这是更有趣的测试.
for (var i = 0; i < 10; i++) {
Service.GetElementsForWebPaged(12, 10, "",
function (result) {
console.log("Elements returned: " + result.length);
},
function (error) {
});
}
Run Code Online (Sandbox Code Playgroud)
结果是"真棒"!
Elements returned: 11
Elements returned: 11
Elements returned: 10
Elements returned: 11
Elements returned: 11
Elements returned: 10
Elements returned: 11
Elements returned: 10
Elements returned: 11
Elements returned: 11
Run Code Online (Sandbox Code Playgroud)
小智 1
测试这个答案会很困难,因为它取决于您的架构和测试数据等。但我相信您可能会遇到将 IQueryAble 结果与 IEnumerable 结果混合在一起的问题。
请记住,在完成 foreach 或 ToList() 之前,linq-To-Entities 查询实际上不会与数据库进行往返。
我建议首先将其分成几部分:
var elementsQuery = from m in entityContext.elements
where m.elementSearchText.Contains(filter)
orderby m.CreatedDate descending;
var elements = elementsQuery.Skip(pageId * countPerPage).Take(countPerPage)).ToList();
Run Code Online (Sandbox Code Playgroud)
然后建立你的投影......
var elementsForWeb = from m in elements
select new DataContracts.ElementForWeb()
{
...
}
Run Code Online (Sandbox Code Playgroud)