ORMLite SQL Server更新
我有一个名为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(";nn", 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 AND“POno “= @ PONO? 几乎看起来好像它试图在没有CaptureSqlFilter的情况下执行INSERT和UPDATE
更新1
该文件称:
限制为了简单起见,为了能够在db4o,memcached,redis或文件系统中保留相同的POCO类(即ServiceStack中包含的提供程序),每个模型必须具有一个主键,按照惯例OrmLite预计它是Id尽管您使用[别名(“DbFieldName”)]]属性将其映射到具有不同名称的列,或者使用[PrimaryKey]属性来指示OrmLite使用主键的其他属性。
您仍然可以从这些表中进行选择,但您将无法使用依赖它的API,例如更新或删除隐含过滤器(即未指定)的地方,以ById结尾的所有API等。
解决方法单一主键限制
支持具有多个主键的表的潜在解决方法是创建一个自动生成的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没有工作? 只是想知道我是否错过了一些东西,或者没有正确理解文档。
哦,并在评论中发帖抱歉!
我所做的事情我需要改变,以便它知道PoNo和ItemCode都是主键
OrmLite的主要限制是每个表都有一个主键 。
您还可以使用内置的分析或调试日志记录来查看生成的SQL,而无需更改代码以使用CaptureSqlFilter
。
我还建议您不要使用请求DTO来定义服务。 您可以使用内置的AutoMapping轻松使用它来填充数据模型。
链接地址: http://www.djcxy.com/p/65973.html