ServiceStack 中的补丁

PATCH in ServiceStack

我正在尝试使用以下代码修补对象。

public object Patch(EditBlog request)
{
     using (var db = _db.Open())
     {
         try
         {
            request.DateUpdated = DateTime.Now;
            Db.Update<Blog>(request, x => x.Id == request.Id);
            return new BlogResponse { Blog = Blog = Db.Select<Blog>(X=>X.Id == request.Id).SingleOrDefault()};
         }
         catch (Exception e)
         {

             return HttpError.Conflict("Something went wrong");
         }
     }
 }

在 Postman 中,我是这样调用函数的 "api/blog/1?=Title=Test1&Summary=Test&UserId=1"。 调试时我可以看到这些值已分配给请求。 在更新期间它抛出:"Cannot update identity column 'Id'"

我的模型是这样的

public class Blog
{
    [AutoIncrement]
    public int Id { get; set; }

    public IUserAuth User { get; set; }
    [Required]
    public int UserId { get; set; }

    [Required]
    public string Title { get; set; }
    public string Summary { get; set; }
    public string CompleteText { get; set; }

    [Required]
    public DateTime DateAdded { get; set; }

    public DateTime DateUpdated { get; set; }

}

EditBlog DTO 如下所示:

[Route("/api/blog/{id}", "PATCH")]
public class EditBlog : IReturn<BlogResponse>
{
    public int Id { get; set; }
    public IUserAuth User { get; set; }
    public int UserId { get; set; }
    public string Title { get; set; }
    public string Summary { get; set; }
    public string CompleteText { get; set; }
    public DateTime DateUpdated { get; set; }
}

错误消息 "Cannot update identity column 'Id'" 在 ServiceStack.OrmLite 中不存在更新带有主键注释的模型,例如您的 Blog class 具有带注释的 [AutoIncrement] Id 主键。

错误出在执行更新的 Db.Up<T> 方法中,它不是 OrmLite API,因此可能是您自己的自定义扩展方法或替代库。

我会在 OrmLite 中使用类似以下内容的 PATCH 请求:

var blog = request.ConvertTo<Blog>();
blog.DateUpdated = DateTime.Now;
Db.UpdateNonDefaults(blog);

即使用 OrmLite 的 UpdateNonDefaults API 仅更新非默认字段并使用 Blog Table POCO 而不是 EditBlog 请求 DTO 进行更新。

另外在获取单条记录时应该使用Single APIs,例如:

Blog = Db.SingleById<Blog>(request.Id)

Blog = Db.Single<Blog>(x => x.Id == request.Id)

而不是:

Blog = Db.Select<Blog>(X=>X.Id == request.Id).SingleOrDefault()