我首先使用Entity Framework代码为我的用户管理数据库后台存储。我有一个“添加用户角色”操作,它将用户从数据库中提取,将该用户添加到该角色,然后保存更改。但是,当我这样做时,用户的新副本将插入到数据库中,其中包含一个新的/不同的ID(唯一键),而不是我从db中提取的用户,我不知道为什么。有关为何发生这种情况的任何想法?
IEnumerable<long> usersIdsToGiveRole = from u in vm.UsersNotInSelectedRole where u.IsSelected select u.Id; // say, yields "5"
IEnumerable<User> usersToGiveRole = _userRepository.InternalUsers.Where(u => usersIdsToGiveRole.Contains(u.ID)); // gets user with ID 5
foreach (var user in usersToGiveRole)
{
selectedRole.UsersWithRole.Add(user);
}
_roleRepository.SaveChanges(); // creates new user with ID 6 cloning all other fields of user 5
答案 0 :(得分:5)
只是猜测:您似乎为_userRepository
和_roleRepository
分别拥有ObjectContexts。通过从您附加到此上下文的usersToGiveRole
加载_userRepository
。 selectedRole
似乎与_roleRepository
的其他背景相关联。当您将user
添加到selectedRole.UsersWithRole
时,请将其添加到第二个上下文(user
现在处于added
状态的_roleRepository
状态。当您调用此上下文的SaveChanges
时,现在会在数据库中创建一个新的User对象。
解决方案:确保您只在两个存储库中使用一个上下文。
修改强>
简而言之:
不要这样做:
class UserRepository
{
private readonly MyContext _context;
public UserRepository()
{
_context = new MyContext();
}
public void SaveChanges()
{
_context.SaveChanges();
}
}
class RoleRepository
{
private readonly MyContext _context;
public RoleRepository()
{
_context = new MyContext();
}
public void SaveChanges()
{
_context.SaveChanges();
}
}
...
var userRepository = new UserRepository();
var roleRepository = new RoleRepository();
// CRUD
userRepository.SaveChanges();
// perhaps other CRUD
roleRepository.SaveChanges();
请执行此操作:
class UserRepository
{
private readonly MyContext _context;
public UserRepository(MyContext context)
{
_context = context;
}
}
class RoleRepository
{
private readonly MyContext _context;
public RoleRepository(MyContext context)
{
_context = context;
}
}
...
using (var context = new MyContext())
{
var userRepository = new UserRepository(context);
var roleRepository = new RoleRepository(context);
// CRUD
context.SaveChanges();
}
上下文(或工作单元)总是高于存储库的级别,应该在外部创建并注入到存储库中。