What I'm trying to do:
I have a table of users and a table of bridges. The relationship between bridges and users is many-to-many. I am given a user and an IEnumerable of bridges, and I'm trying to add the user to each of the bridges in the IEnumerable.
我有一个用户表和一个桥表。桥梁和用户之间的关系是多对多。我有一个用户和一个IEnumerable,我正在尝试将用户添加到IEnumerable中的每个桥上。
What I've Tried:
I've searched, but many posts are about Context.SaveChanges()
being slow. For me, Context.SaveChanges()
is fine. But I have Add()
and Attach()
calls in a loop, and the loop takes 37 seconds to run for n < 150 in debugging mode.
我搜索过,但是很多帖子都是关于Context.SaveChanges()很慢的。对我来说,Context.SaveChanges()很好。但是我在循环中有Add()和Attach()调用,在调试模式下运行n < 150需要37秒。
I've tried turning off AutoDetectChangesEnabled
, but it appears I'm depending on that.
我尝试过关闭AutoDetectChangesEnabled,但它似乎我正在依赖它。
Context.Configuration.ValidateOnSaveEnabled = false;
Context.USER.Add(user);
Context.USER.Attach(user);
foreach(BRIDGE bridge in bridges)
{
Context.BRIDGE.Add(bridge);
Context.BRIDGE.Attach(bridge);
bridge.USER.Add(user);
}
int result = Context.SaveChanges();
Context.Configuration.ValidateOnSaveEnabled = true;
return result;
My Options (as I understand them):
-
Redirect the user and do the operation asynchronously. (Avoiding because I'd like to give the user some feedback after it completes).
重定向用户并异步执行操作。(避免,因为我想在用户完成后给他们一些反馈)。
-
Just make the user wait it out.
让用户等待。
-
Send the relevant info to a stored procedure and have the stored proc
SELECT
the bridges and do theINSERT
. (Avoiding because my workplace will probably frown on it at best.)将相关信息发送到存储过程,并让存储的proc选择桥并执行插入操作。(我尽量避免,因为我的工作场所可能会对此表示不满。)
Question:
Is there any way to make the loop run faster, or am I stuck?
有没有办法让这个循环跑得更快,还是我被卡住了?
(I've only been working with Entity Framework for about 6 months, so the more explanation, the better.)
(我使用实体框架的时间只有6个月左右,所以解释得越多越好。)
1 个解决方案
#1
1
basically you don't need to work with context in the loop, EF saves your entire object graph, instead you can do :
基本上你不需要在循环中使用上下文,EF保存你的整个对象图,相反你可以:
foreach(BRIDGE bridge in bridges)
{
//Context.BRIDGE.Add(bridge); remove this line
//Context.BRIDGE.Attach(bridge); remove this line
bridge.USER.Add(user);
}
Context.BRIDGE.AddRange(bridges);
Context.SaveChanges();
#1
1
basically you don't need to work with context in the loop, EF saves your entire object graph, instead you can do :
基本上你不需要在循环中使用上下文,EF保存你的整个对象图,相反你可以:
foreach(BRIDGE bridge in bridges)
{
//Context.BRIDGE.Add(bridge); remove this line
//Context.BRIDGE.Attach(bridge); remove this line
bridge.USER.Add(user);
}
Context.BRIDGE.AddRange(bridges);
Context.SaveChanges();