实体框架代码前6-当我放入实体状态时出现无效操作异常?可能的EF错误
本文关键字:实体 异常 操作 无效 错误 EF 代码 框架 状态 | 更新日期: 2023-09-27 18:26:21
我有一个问题,实体框架代码的前六个代码工作得如此脱节。当我想将实体标记为已修改时,就会出现问题,该实体的关联属性加载了DbContext的新实例,更确切地说,是我命中的源,然后获得保存。
public List<Venta> Get(Expression<Func<Venta, bool>> predicate)
{
try
{
int num = 0;
List<Venta> ventas = new List<Venta>();
using (_context = new MyContext(MyContext.GetConnectionString()))
{
if (predicate == null)
ventas = _context.Ventas.Include("Mesa").Include("Usuario").Include("Pago").ToList();
else
ventas = _context.Ventas.Include("Mesa").Include("Usuario").Include("Pago").Where(predicate).ToList();
}
//I use the other repo to load related entities
UsuarioRepository userRepo = new UsuarioRepository();
foreach (Venta item in ventas)
{
item.GetType().GetProperty("Usuario").SetValue(item, userRepo.Get(u => u.Id == item.UsuarioId).First(), null);
}
//I use the other repo to load related entities
ProductoRepository prodRepo = new ProductoRepository();
foreach (VentaProducto item in ventas.SelectMany(vta => vta.Detalle).ToList())
{
Producto p = prodRepo.Get(prod => item.ProductoId == prod.Id).First();
item.GetType().GetProperty("Producto").SetValue(item, p, null);
}
ventas.ForEach(vta => vta.State = DomainEntityState.Unchanged);
return ventas;
}
catch (Exception ex)
{
throw new Exception("Error al traer las Ventas", ex);
}
}
public override int Save(Venta venta)
{
int saves = 0;
EntityState state;
EntityState stateProducto;
//New Instance of the context without entities in the DbSet's
using (MyContext context = new MyContext(MyContext.GetConnectionString()))
{
try
{
if (venta.IsNewEntity) //Venta nueva
{
state = EntityState.Added;
stateProducto = EntityState.Modified;
}
else
{
state = EntityState.Modified;
stateProducto = EntityState.Modified;
}
//int usuarios = context.Usuarios.Local.Count; //I get 0
//int productos = context.Productos.Local.Count; //I get 0
//int ventasProductos = context.VentasProducto.Local.Count; // I get 0
venta.Usuario = null;
if (venta.Pago != null)
venta.Pago.Usuario = null;
if (venta.Pago != null)
{
EntityState estadoPago = context.GetEntityState(venta.Pago);
}
//HERE IS THE PROBLEM
context.SetEntityState(venta, state);
saves = context.SaveChanges();
}
catch (Exception ex)
{
throw new Exception("Error al grabar la venta", ex);
}
}
return saves;
}
最后我得到了以下错误。。。。
附加"Jackie.Domain.Entitys.Usuario"类型的实体失败,因为同一类型的另一个实体已具有相同的主键值。如果图中的任何实体具有冲突的键值,则使用"Attach"方法或将实体的状态设置为"Unchanged"或"Modified"时可能会发生这种情况。这可能是因为一些实体是新的,并且尚未接收到数据库生成的键值。在这种情况下,请使用"Add"方法或"Added"实体状态来跟踪图形,然后根据情况将非新实体的状态设置为"Unchanged"或"Modified"。
最奇怪的是,如果我用相同的上下文实例加载所有实体,就不会有这个问题。这会是一个bug吗?别再想别的了。谢谢大家。使用谷歌翻译制作。
对象图中(至少)有两个Usuario
属性-venta.Usuario
和venta.Pago.Usuario
。通过附加venta
实体,这两个Usuario
属性中的实体对象将被附加为Unmodified
。如果这两个属性包含具有相同PK值的Usuario
类的两个不同实例,则当附加第二个实例时,它将抛出您收到的错误。这似乎很有可能,因为您正在通过上下文的不同实例加载导航属性,并在混合中加入一些热切的加载。
中断对context.SetEntityState(venta, state)
的调用,查看这两个Usuario
对象实际上是同一个实例还是具有相同PK值的两个不同实例。