【发布时间】:2016-08-01 18:25:19
【问题描述】:
我一直在测试将 EF 实体项列表传递给 Ajax 调用 (JSON) 的函数的性能和代码可读性。
这里有 4 个备选方案(ItemList1、ItemList2、ItemList3 和 ItemList4)的代码,用于将我的 UserNotification 实体列表传递到 JSON:
public ActionResult GetLatestNotificationItems(int nStart, int nFinish)
{
int nCurrentUserId = User.Identity.GetUserId<int>();
var ItemList1 = (from un in db.UserNotifications
where un.UserId == nCurrentUserId
orderby un.DateCreated descending, un.Id ascending
select new { DateCreated = un.DateCreated, HasBeenSeen = un.HasBeenSeen, Id = un.Id, Message = un.Message, Title = un.Title, UserId = un.UserId, ActionURL = un.ActionURL })
.Skip(nStart)
.Take(nFinish - nStart + 1).ToList();
var ItemList2 = db.UserNotifications.Where(U => U.UserId == nCurrentUserId)
.OrderByDescending(U => U.DateCreated)
.ThenBy(U => U.Id)
.Skip(nStart)
.Take(nFinish - nStart + 1)
.Select(s => new { DateCreated = s.DateCreated, HasBeenSeen = s.HasBeenSeen, Id = s.Id, Message = s.Message, Title = s.Title, UserId = s.UserId, ActionURL = s.ActionURL }).ToList();
*//queryGetLatestNotificationItemsReturnType is just a class with the return types.*
var ItemList3 = db.Database.SqlQuery<queryGetLatestNotificationItemsReturnType>("SELECT Id, DateCreated, HasBeenSeen, Message, Title, UserId, ActionURL from UserNotifications Where UserID = " +
"{0} ORDER BY DateCreated DESC, Id ASC OFFSET {1} ROWS FETCH NEXT {2} ROWS ONLY", nCurrentUserId, nStart, (nFinish - nStart + 1))
.ToList();
//disable ProxyCreation for "ItemList4" option. (To strip entities into POCO objects without the extra unnecessary EF data)
db.Configuration.ProxyCreationEnabled = false;
var ItemList4 = db.UserNotifications.SqlQuery(
"SELECT Id, DateCreated, HasBeenSeen, Message, Title, UserId, ActionURL from UserNotifications Where UserID = " +
"{0} ORDER BY DateCreated DESC, Id ASC OFFSET {1} ROWS FETCH NEXT {2} ROWS ONLY", nCurrentUserId, nStart, (nFinish - nStart + 1))
.ToList();
db.Configuration.ProxyCreationEnabled = true;
return Json(ItemList4, JsonRequestBehavior.AllowGet);
}
这些执行时的时间(每个 3 次):
- ItemList1:28ms、21ms、16ms
- ItemList2:22ms、19ms、18ms
- ItemList3:15ms、4ms、5ms
- ItemList4:18ms、5ms、7ms
现在,问题是,推荐使用哪一种? 因为:
ItemList3 执行速度最快,但需要 POCO EF模型之外的结构创建,并且是RAW SQL而不是 LINQ。
ItemList4 几乎一样快,但它需要使用上下文的 ProxyCreationEnabled 并且也是 RAW SQL 而不是 LINQ。
而且 ItemList1 和 ItemList2 的性能都很差,但它们使用了很好的可编译性、更易于阅读的 LINQ。
【问题讨论】:
-
过早的优化是万恶之源。将 LINQ 编译成 SQL 的性能较差是否会导致用户体验问题?如果没有,不要费心让它更快。
标签: c# sql json entity-framework linq