如何有效地将现有实体从输入列表添加到实体框架中的DB

时间:2016-12-25 13:59:00

标签: c# entity-framework

我有一个具有主键属性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个用户,那么这将非常缓慢......

感谢您的回答:)

1 个答案:

答案 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>