无法使用ADO.NET Entity Framework执行存储过程

时间:2009-04-26 20:47:58

标签: .net vb.net entity-framework stored-procedures ado.net

我创建了一个简单的无参数存储过程,我在下面粘贴了它。我已将存储过程导入到我的实体模型并创建了一个Function Import。永远不会创建模型中的函数,我无法使用ADO.NET实体框架执行此存储过程。我已在XML视图中打开.edmx文件,并确认此存储过程没有错误。我究竟做错了什么?是否真的不可能从实体框架中调用这样一个简单的存储过程?我已将导入函数的返回类型设置为None,看到此存储过程不需要返回任何记录集或值。

存储过程:

ALTER PROC [dbo].[Inventory_Snapshot_Create]

AS

SET NOCOUNT ON

DECLARE @Inventory_Snapshot_ID int

INSERT INTO Inventory_Snapshots (snapshot_timestamp)
VALUES (GETDATE())

SET @Inventory_Snapshot_ID = SCOPE_IDENTITY()

INSERT INTO Inventory_Snapshot_Products (inventory_snapshot_id,
    idProduct, stock)

    SELECT @Inventory_Snapshot_ID, idProduct, stock
    FROM products


SET NOCOUNT OFF

尝试执行存储过程的代码:

Dim db As New MilkModel

db.Inventory_Snapshot_Create()

7 个答案:

答案 0 :(得分:11)

首先将它添加到模型中,然后转到实体容器,然后转到导入函数。

此处详细信息:

http://msdn.microsoft.com/en-us/library/bb896231.aspx

答案 1 :(得分:6)

谢谢,pmarflee。

我实际上是来这里发布我的决议并同时看到你的回复。此代码实际使用实体框架的连接并执行我导入到模型中的存储过程。 Microsoft一直在敦促我们的开发人员使用Entity Framework而不是LINQ to SQL和其他DAL生成器,但EF 真的根本不需要它。在它是一个更完整的解决方案之前,我不会在未来的项目中使用它。

这是我最终做的事情:

Dim db As New MilkModel

'==
'Begin dirty hack to execute parameterless/resultless stored
'procedure using Entity Framework (well, sort of using EF). 
'http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/44a0a7c2-7c1b-43bc-98e0-4d072b94b2ab/
'==
Dim con As DbConnection = db.Connection

con.Open()

Dim cmd As DbCommand = con.CreateCommand()

With cmd
    .CommandType = CommandType.StoredProcedure
    .CommandText = "MilkModel.Inventory_Snapshot_Create"
    .ExecuteNonQuery()
    .Dispose()
End With

con.Dispose()
'==
'End dirty hack
'==

答案 2 :(得分:4)

可以通过EF调用任何存储过程。创建一个SP并将其添加到您的模型中。进一步转到模型浏览器,右键单击sp,然后单击add function import,在这里选择你的SP,然后选择它返回的类型,如果它没有返回任何内容,则选择'None'。如果它返回一个sclar类型,则选择类型,如果它返回一个记录集,则选择complex。点击获取列信息,它将显示返回的列。单击“创建新的复杂类型”。然后单击确定。如果它返回其中一个实体,则单击选项实体并从列表框中选择实体类型。

现在你打电话给你的代码。

如果返回复杂类型,则使用代码:

MyEntities _entities = new MyEntities(); var p = from d in _entities.GetOrderInfo() select d;

如果它什么都没有返回则使用代码: MyEntities _entities = new MyEntities(); _entities.Cancel_Sale(ucode, oid);

进一步查询,请访问

http://dubeyniraj.blogspot.com/

答案 3 :(得分:3)

我认为您不能将存储过程添加到EF模型,除非它与实体上的特定CRUD操作相关联。但是,您可以引用实体容器对象的连接属性来访问EF正在使用的基础ADO.NET连接对象。然后,您可以使用传统的ADO.NET代码调用存储过程。

答案 4 :(得分:1)

如果其他人对此感到奇怪......

存储过程和实体框架的主要问题是需要定义返回类型。例如,如果您有一个从表中返回soem行的存储过程,则需要告知Entity Framework这些行的结构是什么样的。它需要这样才能生成所有代理类并序列化和反序列化。

当你进入模型 - rigkt click - inport函数时,你可以选择一个存储过程,但它希望返回类型是none,标量或实体类型(例如,基于数据库中的表)。如果您愿意,可以添加复杂类型。右键单击模型 - 选择添加 - 复杂类型。然后,您可以定义列及其数据类型。

完成此操作后,您刚刚创建的类将显示在上述实体类型列表下。

答案 5 :(得分:1)

对于我的项目,我实际上使用的是FirebirdSql数据库,我不知道它是否真的适用于实体框架,因为我使用它给了我一些问题而且性能不是很好。

但无论如何,如果我(函数)导入一个带有一些插入操作的存储过程,由于某种原因没有任何反应。换句话说,如果我添加到我的模型(EDCX)这样的SP:

create procedure insert_stuff(thing varchar(40))
returns response(50)
as
begin
    insert into stuffs(thing) values (thing);

    response = 'done!';

    suspend;
end;

然后我用这种方式调用它:

FirebirdContext.InsertStuff("Hi there!"); // it should return an ObjectResult<String>
FirebirdContext.SaveChanges();
实际上没有任何事实发生。什么都没有。既不是例外也不是结果也不是插入,everthing是完美的,没有警告没有编译错误。有趣的是,如果我删除存储过程脚本,删除工作!但没有插入!

该表非常简单,如图所示,我已经导入了其他存储过程并且它们可以正常工作,但是因为它们包含查询,更新和删除,所以在它们插入的情况下......没办法!它可能是Firebird Ado.NET提供程序中的错误吗?或者我必须设置一些我错过的东西?

答案 6 :(得分:0)

如果想避免使用DBCommand,我通过让SP返回一组与实体定义匹配的列来使其工作。