【问题标题】:Update entity framework objects更新实体框架对象
【发布时间】:2009-03-08 14:31:59
【问题描述】:

我使用数据传输对象在实体框架与业务层和用户层之间传输数据。我确实有一些疑问,如果我检索到一个转换为 DTO 的对象,我如何在实体框架中更新正确的对象而不只是插入一个副本?

【问题讨论】:

    标签: entity-framework entity


    【解决方案1】:

    以下代码将从强类型视图更新已在 MVC 中作为控制器参数创建的 EF 4 实体:

    一旦实体被添加到上下文中,似乎技巧是使用 ObjectStateManager 将状态从已添加更改为已修改。

    MyEntities db = new MyEntities();
    db.Product.AddObject(product);
    db.ObjectStateManager.ChangeObjectState(product, System.Data.EntityState.Modified);
    return db.SaveChanges() > 0;
    

    根据@Sean Mills 的评论,如果您使用的是 EF5,请使用:

     ((IObjectContextAdapter) db).ObjectContext.ObjectStateManager.ChangeObjectState(entity, System.Data.EntityState.Added);
    

    【讨论】:

    • 终于!我已经在其他解决方法上浪费了很多时间 - 这非常棒,无需在更新时为每个属性执行 dbObject.Property =passedObject.Property。
    • 如果 ObjectStateManager 不是您的上下文的属性,请尝试 ((System.Data.Entity.Infrastructure.IObjectContextAdapter)db).ObjectContext stackoverflow.com/a/8968643/678338
    【解决方案2】:

    一个老问题,但以防万一有人需要代码解决方案:

    http://www.mikesdotnetting.com/Article/110/ASP.NET-MVC-Entity-Framework-Modifying-One-to-Many-and-Many-to-Many-Relationships

    例子:

    public void EditArticle(
            Article article, string articleTypeId, string[] categoryId) 
    { 
      var id = 0; 
      Article art = de.ArticleSet 
                      .Include("ArticleTypes")
                      .Include("Categories")
                      .Where(a => a.ArticleID == article.ArticleID)
                      .First();
    
      var count = art.Categories.Count;
      for (var i = 0; i < count; i++)
      {
        art.Categories.Remove(art.Categories.ElementAt(i));
        count--;
      }
      foreach (var c in categoryId)
      {
        id = int.Parse(c);
        Category category = de.CategorySet
            .Where(ct => ct.CategoryID == id).First();
        art.Categories.Add(category);
      }
    
      art.Headline = article.Headline;
      art.Abstract = article.Abstract;
      art.Maintext = article.Maintext;
      art.DateAmended = DateTime.Now;
    
      art.ArticleTypesReference.EntityKey = new EntityKey(
                                              "DotnettingEntities.ArticleTypeSet", 
                                              "ArticleTypeID", 
                                              int.Parse(articleTypeId)
                                              );
    
      de.SaveChanges();
    }
    

    【讨论】:

      【解决方案3】:
      //I am replacing player :)
      public ActionResult ProductEdit(string Id, Product product)
      {
          int IdInt = DecyrptParameter(Id);
          MyEntities db = new MyEntities();
      
          var productToDetach = db.Products.FirstOrDefault(p=> p.Id == IdInt);
          if (product == null)
              throw new Exception("Product already deleted"); //I check if exists, maybe additional check if authorised to edit
          db.Detach(productToDetach);
      
          db.AttachTo("Products", product);
          db.ObjectStateManager.ChangeObjectState(product, System.Data.EntityState.Modified);
      
          db.SaveChanges();
          ViewData["Result"] = 1; // successful result
          return View();
      }
      

      【讨论】:

        【解决方案4】:

        您需要在 DTO 中包含一个主键或备用键,然后在更新时将该键匹配回正确的 EF 实体。

        【讨论】:

          【解决方案5】:

          这应该适用于 EF 5:https://stackoverflow.com/a/11749716/540802:

          db.Entry(product).State = EntityState.Modified;
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-05-19
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多