ORMLite SQL Server更新

时间:2015-11-19 21:43:46

标签: servicestack

我有一个名为PODetail的表,主键为POno和ItemCode,我有以下内容:

[Route("/podetail/{POno}/{ItemCode}")]
    public class UpdatePODetail : IReturn<PODetail> {
        public string POno { get; set; }
        public string ItemCode  { get; set; }

        public int ?     QtyPend { get; set; }
        public decimal ? NewPrice { get; set; }
        public bool ? BackOrder { get; set; }
        public string  ActionCode { get; set; }
        public bool ? OpenOrder { get; set; }
    }

 public class PODetailService : Service {
    public object Any(UpdatePODetail request) {
        var podetail =  Db.SingleFmt<PODetail>("ItemCode = {0} AND POno = {1}", request.ItemCode, request.POno);
        // var cap = new CaptureSqlFilter();
        try {
            Db.Update(podetail);
        } catch {
            // var sql = string.Join(";\n\n", cap.SqlStatements.ToArray());
        }
        :
        :

        try {
            Db.Update(podetail);
        } catch (Exception ex) {
            string error = ex.Message;
        }
        return podetail;
    }
}

我在顶部添加了Db.Update调用,只是为了检查是否存在更改列的问题,但是我得到了

  

违反PRIMARY KEY约束'aaaaaPoDetail_PK'。无法插入   对象'dbo.PODetail'中的重复键。

然后我添加了cap =行以查看返回的SQL代码

UPDATE "PODetail" SET "NewItemCode"=@NewItemCode, "POno"=@POno, "Vendor"=@Vendor, "ActionCode"=@ActionCode, "Price"=@Price, "NewPrice"=@NewPrice, "CostPrice"=@CostPrice, "QtyOrd"=@QtyOrd, "QtyRcv"=@QtyRcv, "QtySPO"=@QtySPO, "QtyPend"=@QtyPend, "BackOrder"=@BackOrder, "OpenOrder"=@OpenOrder, "OrderDate"=@OrderDate, "InvoiceNo"=@InvoiceNo, "InvoiceVendor"=@InvoiceVendor, "InvoiceDate"=@InvoiceDate, "InvoiceDiscount"=@InvoiceDiscount, "QtyCancel"=@QtyCancel, "Qtylabels"=@Qtylabels, "REOVendor"=@REOVendor, "CurrentRcvQty"=@CurrentRcvQty, "SOPickQty"=@SOPickQty, "SOItem"=@SOItem, "QtyOther"=@QtyOther, "BackOrderCode"=@BackOrderCode WHERE "ItemCode"=@ItemCode

然后它运行良好的未注释 - 没有例外..如果我删除它会得到主键错误

什么是交易 - 为什么我需要CaptureSqlFilter调用 - 或者我需要更改它以便它知道PoNo和ItemCode都是主键或更新需要说WHERE“ItemCode”= @ ItemCode和“POno”= @ PONo?在没有CaptureSqlFilter的情况下,似乎它似乎尝试执行INSERT与UPDATE

更新1

文件说:

  

限制为简单起见,并且能够拥有相同的POCO类   持久存在db4o,memcached,redis或文件系统上(即   ServiceStack中包含的提供者),每个模型必须有一个   主键,按照惯例,OrmLite希望它是Id,尽管你   使用[Alias(“DbFieldName”)]属性将其映射到带有的列   不同的名称或使用[PrimaryKey]属性告诉OrmLite   为主键使用不同的属性。

     

你仍然可以从这些表中选择,你将无法做到   利用依赖它的API,例如更新或删除的位置   过滤器是隐含的(即未指定),所有以...结尾的API   ById等。

     

解决方法单个主键限制

     

支持具有多个主键的表的潜在解决方法是   创建一个返回唯一值的自动生成的Id属性   基于所有主键字段,

所以我试着添加这个

public class PODetail {
    public string Id { get { return this.ItemCode + "/" + this.POno; } }
    public string ItemCode { get; set; }
    public string NewItemCode { get; set; }
    public string POno { get; set; }
    :
}

但是当它执行时:

Db.SingleFmt<PODetail>

错误输出时ID不是有效的列或列未找到或类似

所以我尝试了

public class PODetail {
    //public string Id { get { return this.ItemCode + "/" + this.POno; } }
    [PrimaryKey]
    public string ItemCode { get; set; }
    public string NewItemCode { get; set; }
    [PrimaryKey]
    public string POno { get; set; }
    :
}

它适用于Db.SingleFmt ...和Db.Update

然后我在CaptureSqlFilter中添加了以查看查询的样子并且我得到了

UPDATE "PODetail" SET "NewItemCode"=@NewItemCode, "Vendor"=@Vendor, "ActionCode"=@ActionCode, "Price"=@Price, "NewPrice"=@NewPrice, "CostPrice"=@CostPrice, "QtyOrd"=@QtyOrd, "QtyRcv"=@QtyRcv, "QtySPO"=@QtySPO, "QtyPend"=@QtyPend, "BackOrder"=@BackOrder, "OpenOrder"=@OpenOrder, "OrderDate"=@OrderDate, "InvoiceNo"=@InvoiceNo, "InvoiceVendor"=@InvoiceVendor, "InvoiceDate"=@InvoiceDate, "InvoiceDiscount"=@InvoiceDiscount, "QtyCancel"=@QtyCancel, "Qtylabels"=@Qtylabels, "REOVendor"=@REOVendor, "CurrentRcvQty"=@CurrentRcvQty, "SOPickQty"=@SOPickQty, "SOItem"=@SOItem, "QtyOther"=@QtyOther, "BackOrderCode"=@BackOrderCode WHERE "ItemCode"=@ItemCode AND "POno"=@POno

这首先是我想要的。

它有效,但是你可以多次拥有[PrimaryKey]属性(看起来如此),那么为什么自动生成的Id没有工作呢?只是想知道我是否遗漏了某些东西或者没有正确理解文档。

哦,抱歉在评论中发帖!

1 个答案:

答案 0 :(得分:0)

  

我做什么我需要改变,以便它知道PoNo和ItemCode   主键

OrmLite's primary limitation表示每个表都有单个主键

此外,您可以使用built-in Profilingdebug logging查看生成的SQL,而无需更改代码以使用CaptureSqlFilter

我还建议您不要使用anything other than defining your Service的请求DTO。您可以使用built-in AutoMapping轻松使用它来填充数据模型。