我一直在测试一个函数的性能和代码可读性,该函数将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次):
现在,问题是,哪一个是推荐使用的? 因为:
ItemList3是最快的执行,但它需要一个POCO 除了EF模型之外的结构创建,而不是RAW SQL LINQ。
ItemList4几乎一样快,但它需要使用上下文的ProxyCreationEnabled,也是RAW SQL而不是LINQ。
并且ItemList1和ItemList2都表现不佳,但它们使用了很好的可编辑,更容易阅读LINQ。
答案 0 :(得分:-1)
你听起来好像在看所有选项......你会考虑QueryFirst吗?
就您的标准而言,对于性能而言,db访问权限是vanilla ADO。没有更快的方法。此外,您不需要创建POCO,它们是在设计时由QueryFirst根据查询返回的模式为您生成的。
你说你喜欢编译linq而不是“raw sql”。您是否在字符串文字中对SQL做出反应?你应该!这种奇怪的文化实践仍在继续,这是一个谜。 QueryFirst允许您将sql 放在自己的文件中。它没有编译为IL,但是在您键入时(使用intellisense)由编辑器验证,在保存文件时由QueryFirst测试运行,并且通常升级到语言状态。然后只需将List<QueryResults>
(由生成的Execute()
方法返回)传递给序列化程序,然后将其移出。请记住,由于DB会说SQL,因此任何其他选项都将在后台生成SQL。为什么不收回控制权?