我使用10+ (取决于用例)调用数据库,只是为了填充我视图中的下拉列表。
如下所示的代码:
ViewBag.FK_Grupe_Predmeta_ID = new SelectList(db.Get_Grupe_Predmeta(userLanguageID).ToList(), "ID", "Naziv");
ViewBag.FK_Klasifikacione_Oznake_ID = new SelectList(db.Get_Klasifikacione_Oznake(userLanguageID).ToList(), "ID", "Naziv");
ViewBag.FK_Stranke_ID = new SelectList(db.Strankes.Where(s => s.Povjerljiv == true), "ID", "Naziv");
ViewBag.FK_Prioriteti_ID = new SelectList(db.Get_Prioriteti(userLanguageID).ToList(), "ID", "Naziv");
ViewBag.odjeljenja = new SelectList(db.Get_Odjeljenja(userLanguageID).OrderBy(x => x.Naziv).ToList(), "ID", "Naziv");
ViewBag.VrstePostupka = new SelectList(db.Vrsta_Postupkas.ToList(), "PK_Vrsta_Postupka_ID", "Naziv_Vrste_Postupka");
我调用存储过程和表。但是当我在同一时间测试多个用户时,我得到了很长的加载时间,有时在几分钟内。
找不到任何方法来进行更少的调用并同时填充ViewBag
。有谁知道在这种情况下最好的方法是什么?
谢谢
发布于 2020-11-16 21:11:11
一种建议是只发送所需字段的投影,而不是将整个实体集传递给SelectList构造函数。除非绝对必要,否则我可能会避免调用存储过程,并让EF与表进行交互以构建最佳查询。
var strankes = db.Stranks
.Where(x => x.Povjerljiv)
.Select(x => new { x.ID, x.Naziv });
ViewBag.FK_Stranke_ID = new SelectList(stranks, "ID", "Naziv");
对于常见的查找,您可以投影到ID和名称(Naziv)的视图模型,然后考虑将这些内容缓存到会话中,以避免每次页面加载时重新加载它们。您的SelectList是从缓存的视图模型构建的,而不是再次访问DB。
确保您的DbContext生存期范围设置不长于每个请求。存活时间更长并且随着时间的推移跟踪更多实体的DbContexts在检索和更新实体时会变得慢得多。它跟踪的越多,当你请求某些东西时,它就会筛选更多的缓存实体,然后转到DB读取更多的实体,然后将这些结果实体与它的本地缓存进行缝合。(用于填充任何相关实体等)为了在快速加载集时获得最大性能,请考虑在查找实体(仅映射FK列)和通过局部范围的有界DbContext读取之间具有最少导航属性的有界上下文。
其他需要注意的性能陷阱是实体可能被序列化并发送到视图的任何地方。具有要查找的导航属性的实体被序列化程序“触及”,最终可能会触发延迟加载,以便一次加载一个相关实体。我的建议是始终将实体投影到ViewModels以发送到视图,以避免像这样的陷阱。由于延迟加载陷阱可能会生成查询,因此它们看起来很像触发查找查询的情况。SQL Profiler对于发现在页面加载时意外生成大量查询的情况非常有用。
https://stackoverflow.com/questions/64860403
复制