在实体框架中填充复杂类型
我有一个复杂类型 SalesOrderHeader ,具有以下属性: 订单号 客户名称 客户编号 POD日期 评论 发票号码
我创建了一个存储过程(函数导入)来填充这些属性。在我的程序中,我使用 uspGetDetails:
第一个 select 语句来获取前 4 个属性 OrderNumber、CustomerName、CustomerNumber、PODate。
第二个选择属性来获取评论
第三个选择属性来获取 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 未被选取。
是否可以通过存储过程中的多个查询来填充一种复杂类型? 如果不是,那么还有什么其他方法可以实现这一目标?
I have a complex type SalesOrderHeader with following properties:
OrderNumber
CustomerName
CustomerNumber
PODate
Comments
Invoice Number
I have created a stored procedure(function import) to populate these properties. In my procedure say uspGetDetails I use:
First select statement to fetch first 4 properties OrderNumber, CustomerName, CustomerNumber, PODate.
Second select Proprty to fetch Comments
3rd Select Property to fetch InvoiceNumber as below
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
And below is my method to execute this procedure to populate 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);
}
PROBLEM: When I Execute this, i get an error saying incompatible data, as the function import is fetching results of only foirst query. the results of 2nd and 3rd query ie comments and InvoiceNumber are not being picked.
Is it possible to populate one complex type by multiple queryies i a stored procedure?
If not then what is the other way to accomplish this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不,当前版本 (4.0) 的 EF 不可能实现这一点。当前版本不支持具有多个结果集的存储过程(过程内有多个选择)。此功能已在 2011 年 6 月 CTP 中预览,应该是 EFv4.5 的一部分(.NET 4.5 的一部分)。
目前,使用返回多个结果集的存储过程的唯一方法是使用 EFExtensions 但代码非常更复杂。
No it is not possible with current version (4.0) of EF. Current version doesn't support stored procedures with multiple result sets (more than one select inside the procedure). This feature was previewed in June 2011 CTP and should be part of EFv4.5 (part of .NET 4.5).
At the moment the only way to use stored procedures returning multiple result sets is to use EFExtensions but the code is much more complicated.
请记住,您的发票号码在过帐之前实际上会以 SOP10100 开始。您需要首先检查 SOP10100 以获取 SOPNUMBE 中的发票编号,然后检查 SOP30200。请记住,SOP10100 是活动 SOP 头表,SOP30200 是历史 SOP 头表。
请注意我上面使用的
IF
语句。使用count(*)
函数来确定您要查找的记录是在活动表还是历史表中,性能负担过重。同样的想法可以用在您的初始查询中:正如 Ladislav 的回答中提到的,您可能需要将此存储过程分解为 3 个不同的存储过程,直到 EF 更新以满足您的项目需求。
Keep in mind that your invoice number will actually start out in SOP10100 before it gets posted. You will need to check SOP10100 first for the invoice number in SOPNUMBE then check SOP30200. Remember, SOP10100 is the active SOP header table and SOP30200 is the historical SOP header table.
Note the
IF
statement I used above. Using thecount(*)
function to determine if the record you are looking for is in the active table or history table is more performance heavy than necessary. The same idea can be used in your initial query:As mentioned in the answer by Ladislav, you will likely need to break this stored procedure up into 3 different stored procedures until EF is updated to meet the demands of your project.