C# 实体框架代码前6个-放置实体状态时出现无效操作异常?可能的EF错误?

C# 实体框架代码前6个-放置实体状态时出现无效操作异常?可能的EF错误?,c#,entity-framework,ef-code-first,code-first,C#,Entity Framework,Ef Code First,Code First,我有一个问题,实体框架代码前六个工作如此断开。当我想将一个实体标记为已修改时,就会出现问题,该实体的关联属性加载了一个新的DbContext实例,更准确地说,是命中的来源,然后得到保存 public List<Venta> Get(Expression<Func<Venta, bool>> predicate) { try { int num = 0; List<V

我有一个问题,实体框架代码前六个工作如此断开。当我想将一个实体标记为已修改时,就会出现问题,该实体的关联属性加载了一个新的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;
    }
公共列表获取(表达式谓词)
{
尝试
{
int num=0;
List ventas=新列表();
使用(_context=new MyContext(MyContext.GetConnectionString()))
{
if(谓词==null)
文塔斯=_context.ventas.Include(“Mesa”).Include(“Usuario”).Include(“Pago”).ToList();
其他的
ventas=_context.ventas.Include(“Mesa”).Include(“Usuario”).Include(“Pago”).Where(谓词).ToList();
}
//我使用其他回购来加载相关实体
UsuarioRepository userRepo=新的UsuarioRepository();
foreach(文塔项目在文塔中)
{
item.GetType().GetProperty(“Usuario”).SetValue(item,userRepo.Get(u=>u.Id==item.UsuarioId).First(),null);
}
//我使用其他回购来加载相关实体
ProductoRepository prodRepo=新ProductoRepository();
foreach(ventas.SelectMany(vta=>vta.Detalle.ToList())中的VentaProducto项)
{
Producto p=prodRepo.Get(prod=>item.ProductoId==prod.Id).First();
item.GetType().GetProperty(“Producto”).SetValue(item,p,null);
}
ForEach(vta=>vta.State=DomainEntityState.Unchanged);
回程静脉;
}
捕获(例外情况除外)
{
抛出新异常(“错误al traer las Ventas”,ex);
}
}
公共覆盖整数保存(文塔文塔)
{
int=0;
实体状态;
实体状态状态产品;
//在DbSet中没有实体的上下文的新实例
使用(MyContext context=newmyContext(MyContext.GetConnectionString())
{
尝试
{
if(venta.IsNewEntity)//venta nueva
{
state=EntityState.Added;
stateProducto=EntityState.Modified;
}
其他的
{
state=EntityState.Modified;
stateProducto=EntityState.Modified;
}
//int usuarios=context.usuarios.Local.Count;//我得到0
//int productos=context.productos.Local.Count;//我得到0
//int-ventasProductos=context.VentasProducto.Local.Count;//我得到0
venta.Usuario=null;
if(venta.Pago!=null)
venta.Pago.Usuario=null;
if(venta.Pago!=null)
{
EntityState estadoPago=context.GetEntityState(venta.Pago);
}
//问题就在这里
SetEntityState(venta,state);
saves=context.SaveChanges();
}
捕获(例外情况除外)
{
抛出新异常(“错误al grabar la venta”,ex);
}
}
返回保存;
}
最后我得到以下错误

附加“Jackie.Domain.Entities.Usuario”类型的实体失败,因为相同类型的另一个实体已具有相同的主键值。如果图形中的任何实体具有冲突的键值,则在使用“Attach”方法或将实体状态设置为“Unchanged”或“Modified”时可能会发生这种情况。这可能是因为某些实体是新的,尚未收到数据库生成的键值。在这种情况下,使用“添加”方法或“添加”实体状态跟踪图形,然后根据需要将非新实体的状态设置为“未更改”或“已修改”

最奇怪的是,如果我加载具有相同上下文实例的所有实体,就不会有这个问题。那会是一只虫子吗?别再想别的了。谢谢大家。由google translator制作。

在对象图中有(至少)两个
Usuario
属性-
venta.Usuario
venta.Pago.Usuario
。通过附加
venta
实体,这两个
Usuario
属性中的实体对象将作为未修改的
附加。如果这两个属性包含具有相同PK值的
Usuario
类的两个不同实例,则当附加第二个实例时,它将抛出您收到的错误。这似乎很有可能,因为您正在通过上下文的不同实例加载导航属性,并将一些急切的加载抛到混合中


在调用
context.SetEntityState(venta,state)
时中断,看看这两个
Usuario
对象实际上是同一个实例还是两个具有相同PK值的不同实例。

该方法似乎被切成两半,很抱歉我赢得了编辑器,请清理并格式化您的代码。删除无用的注释和调试代码(如“//仅用于监视状态”和其他)-此代码甚至可能导致问题。另外,为什么要显示这个
Get
方法?EF中不太可能有bug。您尝试在一个上下文中加载同一个键两次,或者尝试在2个上下文中加载同一个对象实例。我所做的是将实体与上下文一起加载,然后丢弃该上下文,并使用上下文的新实例保存更改。使用相同的PK连接两个实体不是问题,因为我用来记录数据的上下文是一个新实例。谢谢大家的帮助。菲尔,这是问题