【问题标题】:Create, Update, Delete Child Entities With .net WebAPI使用 .net WebAPI 创建、更新、删除子实体
【发布时间】:2013-08-08 00:00:38
【问题描述】:

为了更新实体,我使用 http PUT,将更新后的对象作为请求正文传递:

PUT /api/flareform/3

{
    "JobId" : "12-12-4004",
    "Id" : 3,
    "Tasks" : [
      {
        "Hazard" : "Clumsyness",
        "Id" : 2,
        "FlareFormId" : 3,
        "Task" : "Hammering",
        "Control" : "Make Someone Else Hold the Nail"
      },
      {
        "Hazard" : "Nails",
        "Id" : 3,
        "FlareFormId" : 3,
        "Task" : "Walking",
        "Control" : "Keep area clean."
      }
    ],
    "PercentComplete" : null,
    "Time" : "3pm",
    "Initials" : "JD"
}

如果我更新对象的简单属性(例如 Initials),这将正常工作。是否有可能/如何更新、添加、删除任务。可以通过这个对象吗?我想做的只是传递一个更新的任务数组并让它更新/删除/添加所有内容:

PUT /api/flareform/3

{
    "JobId" : "12-12-4004",
    "Id" : 3,
    "Tasks" : [
      {
        "Hazard" : "NewAndImprovedValue",
        "Id" : 2,
        "FlareFormId" : 3,
        "Task" : "NewAndImprovedValue",
        "Control" : "NewAndImprovedValue"
      },
      {
        "Hazard" : "SomeNewItemThatDidntExistBefore",
        "FlareFormId" : 3,
        "Task" : "NoteTheMissingId",
        "Control" : "ShouldAddThisOne"
      }
    ],
    "PercentComplete" : null,
    "Time" : "3pm",
    "Initials" : "JD"
}

【问题讨论】:

  • 能否在服务器端包含DTO的定义? (即 c# 或 VB.net 类)

标签: c# .net json entity-framework asp.net-web-api


【解决方案1】:

您的 Json 对象看起来不错。我相信罪魁祸首是你的 DAL。因为保存子实体并不像人们想象的那么简单。

我假设您的 Tasks 与主要对象是一对多的关系。如果是这样,您需要手动检测任何更改(添加、删除或修改)并应用它们。

本教程应该可以帮助您入门:http://www.entityframeworktutorial.net/update-one-to-many-entities-in-entity-framework.aspx

【讨论】:

    【解决方案2】:

    这或多或少是我最终使用的。我正在尝试以更通用的方式编写此代码,这样我就不必为每个需要更新的子属性复制/粘贴此代码...

        // PUT api/FlareForm/5
        public HttpResponseMessage PutFlareForm(int id, FlareForm flareform)
        {
            if (!ModelState.IsValid)
            {
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
            }
    
            if (id != flareform.Id)
            {
                return Request.CreateResponse(HttpStatusCode.BadRequest);
            }
    
    
            List<int> previousIds = db.FlareForms.AsNoTracking().FirstOrDefault(ff => ff.Id == id).Tasks.Select(t => t.Id).ToList();
            List<int> currentIds = flareform.Tasks.Select(t => t.Id).ToList();
            List<int> deletedIds = previousIds
                .Except(currentIds).ToList();
    
    
            foreach (var deletedId in deletedIds)
            {
                FlareFormTask task = db.FlareFormTasks
                    .Single(od => od.FlareFormId == flareform.Id && od.Id == deletedId);
    
                db.Entry(task).State = EntityState.Deleted;
            }
    
            foreach (var task in flareform.Tasks)
            {
                if (task.Id == 0)
                {
                    task.FlareFormId = flareform.Id;
                    db.Entry(task).State = EntityState.Added;
                }
                else
                {
                    db.Entry(task).State = EntityState.Modified;
                }
            }
    
    
            db.Entry(flareform).State = EntityState.Modified;
    
            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
            }
    
            return Request.CreateResponse(HttpStatusCode.OK);
        }
    

    【讨论】:

    • 我意识到这已经过时了,但我一直在寻找不同的答案并偶然发现了这一点。这可能对您和对我一样有用:github.com/refactorthis/GraphDiff
    猜你喜欢
    • 1970-01-01
    • 2016-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-30
    • 2016-12-11
    • 2012-09-26
    • 1970-01-01
    相关资源
    最近更新 更多