在实体框架中填充复杂类型

时间:2011-12-22 15:28:23

标签: sql-server asp.net-mvc-3 entity-framework .net-4.0 ado.net-entity-data-model

我有一个具有以下属性的复杂类型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没有被选中。

是否可以通过多个查询在存储过程中填充一个复杂类型? 如果没有,那么另一种方法是什么呢?

2 个答案:

答案 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个不同的存储过程。