我有一个具有以下属性的复杂类型SalesOrderHeader: 订单号 顾客姓名 顾客号码 PODate 评论 发票编号
我已经创建了一个存储过程(函数导入)来填充这些属性。在我的程序中说uspGetDetails我使用:
首先选择语句来获取前4个属性OrderNumber,CustomerName,CustomerNumber,PODate。
第二个选择Proprty来获取评论
第三个选择属性以获取InvoiceNumber,如下所示
CREATE PROCEDURE uspGetHeaderDetails
-- Add the parameters for the stored procedure here
@OrderNumber CHAR(21)
AS
BEGIN
DECLARE @Counter INT;
DECLARE @OrignalNumber INT;
SELECT @Counter = count(*) FROM sop10100 WHERE sopnumbe = @OrderNumber
IF @Counter > 0
BEGIN
SELECT TOP 1 sopnumbe [OrderNumber]
, custname [CustomerName]
, custnmbr [CustomerNumber]
, cstponbr [CustomerPhoneNumber]
, docdate [PODate]
, orignumb [OriginalNumber]
FROM sop10100
WHERE sopnumbe = @OrderNumber
END
ELSE
BEGIN
SELECT TOP 1 sopnumbe [OrderNumber]
, custname [CustomerName]
, custnmbr [CustomerNumber]
, cstponbr [CustomerPhoneNumber]
, docdate [PODate]
, orignumb [OriginalNumber]
FROM SOP30200
WHERE sopnumbe = @OrderNumber
END
SELECT cmmttext [Comments]
FROM sop10106 WHERE sopnumbe = @OrderNumber
SELECT sopnumbe [InvoiceNumber]
FROM sop30200 WHERE orignumb = @OrderNumber
END
以下是执行此过程以填充SalesOrderHeader
的方法[AcceptVerbs("POST")]
public ActionResult SearchResult(FormCollection collection )
{
string orderNumber = collection["searchItem"].ToString();
Models.SalesEntities db = new Models.SalesEntities();
ObjectParameter[] parameters = new ObjectParameter[1];
parameters[0] = new ObjectParameter("OrderNumber", orderNumber);
var headerResult = db.ExecuteFunction<Models.SalesOrderHeader>("uspGetHeaderDetails", parameters);
Models.SalesOrderHeader salesOrderHeader = new Models.SalesOrderHeader();
salesOrderHeader = headerResult.SingleOrDefault();
return View(salesOrderHeader);
}
问题:当我执行此操作时,我收到一条错误,指出数据不兼容,因为函数导入仅获取第一次查询的结果。第二次和第三次查询的结果,即评论和InvoiceNumber没有被选中。
是否可以通过多个查询在存储过程中填充一个复杂类型? 如果没有,那么另一种方法是什么呢?
答案 0 :(得分:1)
目前的EF版本(4.0)是不可能的。当前版本不支持具有多个结果集的存储过程(在过程内有多个select)。此功能已在2011年6月的CTP中预览,应该是EFv4.5(.NET 4.5的一部分)的一部分。
目前使用存储过程返回多个结果集的唯一方法是使用EFExtensions,但代码很多more complicated。
答案 1 :(得分:0)
请注意,您的发票号码实际上会在发布之前在SOP10100中开始。您需要首先检查SOP10100以获取SOPNUMBE中的发票编号,然后检查SOP30200。请记住,SOP10100是主动SOP标头表,SOP30200是历史SOP标头表。
IF EXISTS (SELECT 1 FROM SOP10100 WHERE ORIGNUMB = @OrderNumber)
BEGIN
SELECT SOPNUMBE [InvoiceNumber]
FROM SOP10100 WHERE ORIGNUMB = @OrderNumber
END
ELSE
BEGIN
SELECT SOPNUMBE [InvoiceNumber]
FROM SOP30200 WHERE ORIGNUMB = @OrderNumber
END
请注意我上面使用的IF
语句。使用count(*)
函数来确定您要查找的记录是在活动表还是历史记录表中,其性能比必要的要大。您可以在初始查询中使用相同的想法:
IF EXISTS (SELECT 1 FROM SOP10100 WHERE SOPNUMBE = @OrderNumber)
BEGIN
SELECT TOP 1 SOPNUMBE [OrderNumber]
, CUSTNAME [CustomerName]
, CUSTNMBR [CustomerNumber]
, CSTPONBR [CustomerPhoneNumber]
, DOCDATE [PODate]
, ORIGNUMB [OriginalNumber]
FROM SOP10100
WHERE SOPNUMBE = @OrderNumber
END
ELSE
BEGIN
SELECT TOP 1 SOPNUMBE [OrderNumber]
, CUSTNAME [CustomerName]
, CUSTNMBR [CustomerNumber]
, CSTPONBR [CustomerPhoneNumber]
, DOCDATE [PODate]
, ORIGNUMB [OriginalNumber]
FROM SOP30200
WHERE SOPNUMBE = @OrderNumber
END
正如Ladislav的回答中所提到的,在更新EF以满足项目需求之前,您可能需要将此存储过程分解为3个不同的存储过程。