我有一个使用EF向数据库添加大量数据的程序。其中一个数据是一个在数据库中应该是唯一的记录,所以,我有这个指令:
DataWare.Funcionario funcionario = db.Funcionario.Where(f => f.FunRut.Equals(rut)).FirstOrDefault();
如果" funcionario"找不到新的对象,并以这种方式添加到上下文中:
db.Funcionario.Add(funcionario);
这是一个foreach cicle。在某些迭代中,我们遇到相同的" funcionario",上面的Where方法返回null,即使它已经被添加到上下文中。
在foreach之后,我将更改保存到上下文中。
我一直在搜索,我发现该方法总是查询数据库,我可以使用Local属性查询已经在上下文中的对象,但是,这样我有2个问题。首先,它总是仅查询Local实例,因此我需要显式地进行2次调用,以便在上下文中找不到数据库时查询数据库。第二个问题,也就是最糟糕的问题是,当我将SaveChanges调用到上下文时,它会保存许多相同记录的重复项。我不知道为什么。可能这是因为本地和数据库数据未同步。
任何帮助将不胜感激。
由于 海梅
编辑:
这是实际情况:我有一个List<>这实际上为公司员工存储了大量的考勤活动。那个事件来自考勤设备。
我所谈论的foreach是通过该列表的foreach。该事件和工作人员应该在我的数据库中创建,以防它尚不存在。
如果员工不存在,系统会远程调用另一个系统来检索员工信息,然后将该信息保存到我们自己的系统中。如果已添加人员,则应使用该实例而不是创建新实例。顺便说一句,同一个工作人员可以在白天产生几个事件。因此,我将该事件添加到我自己的系统中,以关联找到的员工或新创建的员工。
这是foreach的完整代码供您参考:
using (DataWare.SistemasBCIEntities db = new DataWare.SistemasBCIEntities())
{
bool exito = false;
foreach (var log in logs.OrderBy(l => l.EnrollNumber))
{
string rut = log.EnrollNumber.ToString();
DataWare.Funcionario funcionario = db.Funcionario.Where(f => f.FunRut.Equals(rut)).FirstOrDefault();
if (funcionario == null)
funcionario = GetPersonFromZKTime(rut, db);
if (funcionario != null)
{
// Si ya hay un evento para esa hora y ese funcionario, debe continuar con el siguiente
DataWare.Evento evento = db.Evento.Where(e => e.EveFechaHora.Equals(log.Date) && e.Funcionario.FunRut.Equals(rut)).FirstOrDefault();
if (evento == null)
{
exito = true;
string tipoEvento = String.Empty;
if (log.InOutMode == DataWare.Terminal.InOutModeEnum.Check_In || log.InOutMode == DataWare.Terminal.InOutModeEnum.OT_In || log.InOutMode == DataWare.Terminal.InOutModeEnum.Break_In)
tipoEvento = "IN";
else
tipoEvento = "OUT";
evento = new DataWare.Evento()
{
Funcionario = funcionario,
EveFechaHora = log.Date,
EveTipo = tipoEvento,
EveFechaCreacion = DateTime.Now
};
db.Evento.Add(evento);
}
}
}
db.SaveChanges();
return exito;
}
答案 0 :(得分:0)
你可能只是检查是否已设置id,否则设置实体状态如下:
foreach(var rut in source.Distinct())
{
db.Entry(rut).State = rut.Id == 0 ?
EntityState.Added :
EntityState.Modified;
}
答案 1 :(得分:0)
我已经将用于查找记录的字段更改为主键,然后我使用了EF的Find方法,它按预期工作。