假设我有两个实体,每个实体有大约20个属性,并且像是这样的多对多关系:
User (Id int,Name string, .......)
Issue (Id int,Name string, .......)
IssueAssignment (UserId,RoleId)
我想创建一个新问题并将其分配给许多现有用户。如果我有这样的代码:
foreach(var userId in existingUserIds)
{
int id = userId
var user = _db.Users.First(r => r.Id == id);
issue.AssignedUsers.add(user);
}
_db.Users.AddObject(user);
_db.SaveChanges();
我注意到,当我针对我的SQL数据库运行它时,效率似乎非常低效。如果我看看 SQL Profiler正在执行以下操作:
我的问题是:
(a)为什么(1)和(2)必须发生?
(b)(1)和(2)都将我需要做的所有字段带回来进行对象投影来限制
田野,似乎也是不必要的工作。
感谢您的帮助
答案 0 :(得分:4)
我有一些可能的线索:
_db.Users
实际上是一个查询,在查询上调用First
意味着在数据库中执行查询。 User
添加Issue
,它就会在内部触发修正并尝试将Issue
添加到User
1}}。这反过来会触发与用户相关的所有问题的延迟加载。所以诀窍是使用虚拟对象而不是真实用户。你知道id,你只想在新问题和现有用户之间创建实现。试试这个(适用于EFv4 +和POCO):
foreach(var userId in existingUserIds)
{
var user = new User { Id = userId };
var _db.Users.Attach(user); // User with this Id mustn't be already loaded
issue.AssignedUsers.Add(user);
}
context.Issues.AddObject(issue);
context.SaveChanges();