我在实体框架4上剥了皮,遇到了一个小问题。
我有一些存储过程,我将其添加到EDMX中。当我从这些过程创建复杂类型时,EF获取列信息没有问题。除了在一个地方。在困惑了一段时间后,我发现这是我的临时表填充,导致问题。实际上它只是将INSERT调用到导致问题的临时表中。我实际上并没有用任何信息填充它。
虽然我知道我可以手动创建复杂类型然后将函数映射到该类型,但我希望能够让EF为我处理它。有谁知道我做错了什么?
以下是一个不起作用的示例过程。在DB中运行它并将proc添加到EDMX。然后尝试在“添加功能导入”屏幕中获取列信息。什么都没有归还。将INSERT注释到临时表并获取列信息并且它可以正常工作。
谢谢, 史蒂夫
CREATE PROCEDURE dbo.TestProc
AS
SET NOCOUNT ON
CREATE TABLE #TempTable(
StartDate datetime
)
INSERT INTO #TempTable
SELECT null
DROP TABLE #TempTable
SELECT 1 AS ReturnValue
SET NOCOUNT OFF
GO
答案 0 :(得分:6)
要尝试的一些事情。
尝试使用以下存储过程(未经测试......只是大声思考......)
CREATE PROCEDURE dbo.Foo
AS
SET NOCOUNT ON
DECLARE @ResultTable TABLE (SomeId INTEGER)
INSERT INTO @ResultTable
SELECT DISTINCT Id AS Identity -- Or u can rename this field to anything...
FROM SomeExistingTableWhichHasAnIdentityField
GO
尝试并立即查看向导是否刷新。
-
好的..当EF设计师/向导/无法确切地弄清楚我的存储过程假设要返回的内容时,我通常会执行以下操作: -
/* /*
注释一切。例如..
ALTER PROCEDURE dbo.Foo
(
Bar1 INT,
Bar2 TINYINT,
... // whatever u have as your optional input arguments //
)
AS
SET NOCOUNT ON
/*
.... every thing in here is commented out
*/
GO
现在...... 3.在存储过程中添加强制虚假返回,其中(或多或少)只是定义输出结构/字段。
例如..
ALTER PROCEDURE dbo.Foo
(
Bar1 INT,
Bar2 TINYINT,
... // whatever u have as your optional input arguments //
)
AS
SET NOCOUNT ON
SELECT 1 AS Id, 1 AS UserId, 1 AS SomeOtherId,
CAST('AAA' AS NVARCHAR(350)) AS Name,
-- etc etc etc..
/*
.... every thing in here is commented out
*/
GO
and then ...
...现在EF已更新,并且不知道我们已经更改了存储过程的管道。
胜利:)。
这适用于你吗?
答案 1 :(得分:1)
这是Pure.Krome的优秀答案的变体。而不是注释掉你的sproc代码,创建一个只包含Pure描述的“假”选择语句的新视图。该视图将用于创建实体。然后,视图实体成为存储过程结果的容器。
Create View dbo.FooWrapperView as
Select IsNull(MyPrimaryID,-999) as IntFieldName, --IsNull disallows nulls so EF designer will make this the primary key.
NullIf(CAST('AAA' as VarChar(20)), '') as VarChar20FieldName, --NullIf allows null so EF designer will NOT make this part of the primary key.
NullIf(CAST('AAA' as VarChar(42)), '') as VarChar42FieldName,
NullIf(CAST(1.1 as DECIMAL(8, 5)), '') as Decimal85FieldName
在实体设计器中右键单击并选择“从数据库更新模型”,然后选择包装器视图(如果尚未选择,则选择sproc)。这将创建映射到伪造包装器视图的实体。设计者根据视图的IsNull和NullIf语句(details here)选择主键。在模型浏览器中找到sproc。右键单击它并选择“添加函数导入...”。在“返回一个集合”下选择实体。选择视图实体,然后单击“确定”。现在,当您调用存储过程时,它会将结果转储到您的视图实体中。
MyProject.MyEntities myContext = new MyProject.MyEntities();
var myQuery = myContext.usp_FOO(myRecordID);
FooWrapperViewEntity myFooEntity = new FooWrapperViewEntity();
myFooEntity = myQuery.FirstOrDefault();
答案 2 :(得分:0)
首先,您必须在不使用临时表的情况下创建正常的存储过程。此存储过程将包含所有列名称(普通表+临时表)。现在可以在EDMX中创建复杂类型