问题描述
我正在使用Entity Framework代码来管理我的用户的数据库后台。我有一个添加角色到用户操作,从db中提取用户,将该用户添加到角色,然后保存更改。但是,当我这样做时,用户的新副本将使用新的/不同的ID(唯一键)插入到数据库中,而不是从数据库中提取的用户,我不知道为什么。任何关于为什么会发生这种情况的想法?
I'm using Entity Framework code first to manage a database backstore for my users. I have an "add role to user" operation that pulls a user from the db, adds that user to the role, and then saves changes. However, when I do this a new copy of the user is inserted into the database with a new/different ID (unique key) than the user I pulled from the db and I'm not sure why. Any thoughts on why this is happening?
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
推荐答案
只是一个猜测:您似乎有独立的ObjectContexts for _userRepository
和 _roleRepository
。通过从 _userRepository
加载 usersToGiveRole
,您将附加到此上下文。 selectedRole
似乎附加到 _roleRepository
的其他上下文中。当您将用户
添加到 selectedRole.UsersWithRole
时,将其添加到此第二个上下文(用户
现在在中添加
状态在 _roleRepository
的上下文中)。当您调用此上下文的 SaveChanges
时,将在数据库中创建一个新的User对象。
Just a guess: You seem to have separate ObjectContexts for _userRepository
and for _roleRepository
. By loading usersToGiveRole
from the _userRepository
you attach to this context. selectedRole
seems to be attached to the other context of _roleRepository
. When you add the user
to selectedRole.UsersWithRole
you add it to this second context (user
is now in added
state in the context of _roleRepository
). When you call SaveChanges
of this context now a new User object is created in the database.
解决方案:确保您只在两个存储库中使用一个单一的上下文。
Solution: Make sure that you only use one single context in both repositories.
修改
简短的意思是:
不要这样做:
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();
}
上下文(或工作单位)总是位于资源库之上,应在外部创建并注入回收站。
The context (or Unit of Work) is always a level above the repositories, should be created outside and injected into the repos.
这篇关于将用户添加到角色将重复的用户插入到users表中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!