C# 使用实体框架在foreach内部分配对象非常慢
我在使用Entity Framework在foreach循环中分配对象时遇到问题,我不知道为什么要花很长时间(循环中1800个项目的分配时间几乎为48秒!!) 示例代码:C# 使用实体框架在foreach内部分配对象非常慢,c#,asp.net,entity-framework,foreach,linq-to-sql,C#,Asp.net,Entity Framework,Foreach,Linq To Sql,我在使用Entity Framework在foreach循环中分配对象时遇到问题,我不知道为什么要花很长时间(循环中1800个项目的分配时间几乎为48秒!!) 示例代码: using (var db = new MyEntities()) { foreach (long r in Recipients) //Recipients has 1800 items. { var temp = new DirectMessage(); temp =
using (var db = new MyEntities())
{
foreach (long r in Recipients) //Recipients has 1800 items.
{
var temp = new DirectMessage();
temp = db.DirectMessages().FirstOrDefault();
temp.SenderProfileImageUrl = "https://www.google.com.sa/images/branding/googlelogo/2x/googlelogo_color_120x44dp.png";
}
}
这个简单的循环大约需要45秒
在测试和调试时,我注意到这个命令temp=db.DirectMessages().FirstOrDefault()代码>正在进行延迟
另外,最初它使用r.ID
使用Where
和.OrderBy
,但我将其更改为最简单的方法,以确保延迟不是来自过滤
更新,原始代码:
foreach (long r in Recipients)
{
MsgObj = new AllMsgsClass();
MsgObj.LastMsg = db.DirectMessages.Where(a => (a.SenderID == r || a.RecipientID == r)).OrderByDescending(a => a.CreatedDate).AsNoTracking().FirstOrDefault();
try
{
if (MsgObj.LastMsg.MsgSort == "Sent")
MsgObj.LastMsg.RecipientProfileImageUrl = "https://avatars.io/twitter/" + MsgObj.LastMsg.RecipientScreenName + "/small";
else
MsgObj.LastMsg.SenderProfileImageUrl = "https://avatars.io/twitter/" + MsgObj.LastMsg.SenderScreenName + "/small";
}
catch (Exception dd)
{
string x = dd.Message;
}
MsgObj.SortOrder = Convert.ToDateTime(MsgObj.LastMsg.CreatedDate);
AllMSGsList.Add(MsgObj);
}
任何帮助都将不胜感激 如果db.DirectMessages().FirstOrDefault()
在每次迭代中调用数据库,则需要时间。为什么不改用这个呢
using (var db = new MyEntities())
{
var directMessage = db.DirectMessages().FirstOrDefault();
foreach (long r in Recipients) //Recipients has 1800 items.
{
var temp = new DirectMessage();
temp = directMessage;
temp.SenderProfileImageUrl = "https://www.google.com.sa/images/branding/googlelogo/2x/googlelogo_color_120x44dp.png";
}
}
最新答复:
var directMessages = db.DirectMessages.ToList();
foreach (long r in Recipients)
{
MsgObj = new AllMsgsClass();
MsgObj.LastMsg = directMessages.Where(a => (a.SenderID == r || a.RecipientID == r)).OrderByDescending(a => a.CreatedDate).AsNoTracking().FirstOrDefault();
try
{
if (MsgObj.LastMsg.MsgSort == "Sent")
MsgObj.LastMsg.RecipientProfileImageUrl = "https://avatars.io/twitter/" + MsgObj.LastMsg.RecipientScreenName + "/small";
else
MsgObj.LastMsg.SenderProfileImageUrl = "https://avatars.io/twitter/" + MsgObj.LastMsg.SenderScreenName + "/small";
}
catch (Exception dd)
{
string x = dd.Message;
}
MsgObj.SortOrder = Convert.ToDateTime(MsgObj.LastMsg.CreatedDate);
AllMSGsList.Add(MsgObj);
}
一旦我遇到了类似的问题,并且遵循了以下步骤,我希望这将对您有所帮助。
这也有助于更快地生成edmx。
将数据库的兼容性级别设置为110对我来说很有效。
要检查兼容性级别,请运行以下脚本:
select compatibility_level from sys.databases where name = 'YOUR_DB_NAME'
alter database YOUR_DB_NAME set compatibility_level = 110
要设置兼容性级别,请使用以下脚本:
select compatibility_level from sys.databases where name = 'YOUR_DB_NAME'
alter database YOUR_DB_NAME set compatibility_level = 110
您真的需要从DB重新查询同一项1800次吗?为什么不将此项缓存到局部变量中?不幸的是,我有两个原因,按用户ID获取最新的配置文件图片(在问题中,我刚刚放置了google图标),并在绑定之前进行排序。您可以发布您的真实代码吗?@Dennis Posted,谢谢您需要检索查询执行计划,并对其进行分析。对于SQL Server,请使用Management Studio。因为我实际上并没有调用FirstOrDefault,所以我只是这样做来测试where子句是否不是问题所在。原始命令是:temp=db.DirectMessages.Where(a=>(a.SenderID==r | | a.RecipientID==r)).OrderByDescending(a=>a.CreatedDate).AsNoTracking().FirstOrDefault();是否需要在每次迭代时调用数据库?我更新了问题,添加了真实的代码,因此也许您可以了解我为什么需要在每次迭代时调用数据库。如果可以使用db.DirectMessages.ToList();对于一个变量并从中进行迭代,可以将数据库调用从1800保存到1。在新的更改之前,您可能不需要再次调用数据库。我已经更新了答案。宾果!不到一秒钟就成功了!!!!这确实有道理!不是每次迭代都到达数据库,而是访问本地列表。。非常感谢。