我有一个名为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
文件说:
限制为简单起见,并且能够拥有相同的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没有工作呢?只是想知道我是否遗漏了某些东西或者没有正确理解文档。
哦,抱歉在评论中发帖!
答案 0 :(得分:0)
我做什么我需要改变,以便它知道PoNo和ItemCode 主键
OrmLite's primary limitation表示每个表都有单个主键。
此外,您可以使用built-in Profiling或debug logging查看生成的SQL,而无需更改代码以使用CaptureSqlFilter
。
我还建议您不要使用anything other than defining your Service的请求DTO。您可以使用built-in AutoMapping轻松使用它来填充数据模型。