我有一个具有主键属性User
的实体UCO
。
我想编写一个方法AddUsers
,将给定列表中的所有用户添加到数据库中。问题是当管理员尝试添加列表时,该列表中的用户已经存在于数据库中,然后抛出异常。
我的解决方案只添加不在数据库中的用户:
public void AddUsers(List<UserDTO> users)
{
using (var db = new AppDbContext())
{
var existingUsers = Mapper.Map<List<UserDTO>>(db.Users.ToList());
db.Users.AddRange(
Mapper.Map<List<User>>(users
.Where(user => !existingUsers
.Select(u => u.UCO)
.Contains(user.UCO))));
db.SaveChanges();
}
}
我想问一下是否有更有效的解决方案。如果我有10和39个用户,那么这将非常缓慢......
感谢您的回答:)
答案 0 :(得分:1)
如果预计users
列表不会那么大,您可以避免至少以两种方式加载可能很大的existingUsers
列表。
首先,对users
列表中的每个项目执行单个数据库查询(完全users.Count
个查询):
using (var db = new AppDbContext())
{
db.Users.AddRange(Mapper.Map<List<User>>(users
.Where(user => !db.Users.Any(u => u.UCO == user.UCO))));
db.SaveChanges();
}
其次,执行单个数据库查询以从数据库中存在的UCO
列表中检索项目的users
子集,然后使用它从add中排除它们:
using (var db = new AppDbContext())
{
var userUCOs = users.Select(u => u.UCO);
var existingUserUCOs = new HashSet<int>(db.Users
.Where(u => userUCOs.Contains(u.UCO))
.Select(u => u.UCO));
db.Users.AddRange(Mapper.Map<List<User>>(users
.Where(u => !existingUserUCOs.Contains(u.UCO))));
db.SaveChanges();
}
(如果UCO
类型不是int
,请使用HashSet<UCO_Type>
)