代码之家  ›  专栏  ›  技术社区  ›  Oleg Sh

将具有树的实体附着到EF

  •  1
  • Oleg Sh  · 技术社区  · 7 年前

    我有一个包含许多子实体的巨大表单,所以,我使用Automapper用树填充EF对象。然后我想更新数据库中类似的实体。有没有办法把它和上下文联系起来?

            // ApplicationDriver has many child objects
            Infrastructure.Asset.ApplicationDriver driver = mapper.Map<Infrastructure.Asset.ApplicationDriver>(model);
    
            // get similar object from DB
            Infrastructure.Asset.ApplicationDriver currentApplication = db.ApplicationDrivers.Where(p => p.ApplicationId == model.ApplicationId).FirstOrDefault();
    
            if (currentApplication == null)
            {
                db.ApplicationDrivers.Add(driver);
            }
            else
            {
                // try to attach driver to current context. 
                // I want to 'replace' current object with all child objects in DB
                db.ApplicationDrivers.Attach(driver);
                currentApplication = driver;
            }
            await db.SaveChangesAsync();
    

    我收到一个错误:

    失败,因为相同类型的另一个实体已具有相同的 主键值。使用“附加”方法或 将实体的状态设置为“未更改”或“已修改”(如果有) 图中的实体具有冲突的键值。这可能是因为 价值观在这种情况下,使用“Add”方法或“Added”实体状态 跟踪图形,然后将非新实体的状态设置为 “未更改”或“已修改”(视情况而定)。"

            var currentApplication = db.ApplicationDrivers.Where(p => p.ApplicationId == model.ApplicationId).FirstOrDefault();
    
            if (currentApplication == null)
            {
                db.ApplicationDrivers.Add(driver);
            }
            else
            {
                driver.Id = currentApplication.Id;
                db.ApplicationDrivers.Attach(driver);
            }
            await db.SaveChangesAsync();
    

    得到同样的错误。有什么不正确的地方,如何在不手动将所有子对象的每个属性从驱动程序复制到当前应用程序的情况下解决这个问题?

    2 回复  |  直到 7 年前
        1
  •  0
  •   farzaaaan    7 年前

        // ApplicationDriver has many child objects
        Infrastructure.Asset.ApplicationDriver driver = mapper.Map<Infrastructure.Asset.ApplicationDriver>(model);
    
        // get similar object from DB
        Infrastructure.Asset.ApplicationDriver currentApplication = db.ApplicationDrivers.Where(p => p.ApplicationId == model.ApplicationId).FirstOrDefault();
    
        if (currentApplication == null)
        {
            db.ApplicationDrivers.Add(driver);
        }
        else
        {
            //this will attach, and set state to modified
            //same as previous question, make sure you virtual properties are not populated to avoid unwanted duplicates. 
            db.Entry(driver).State = System.Data.Entity.EntityState.Modified; 
            currentApplication = driver;
        }
        await db.SaveChangesAsync();
    
        2
  •  0
  •   Oleg Sh    7 年前

    我发现了一篇文章:

    https://www.devtrends.co.uk/blog/stop-using-automapper-in-your-data-access-code

    似乎,最好不要使用automapper将DTO映射到EF进行编辑。。