使用Entity Framework从存储过程中获取数据

时间:2015-08-21 12:50:06

标签: c# asp.net sql-server entity-framework stored-procedures

我正在尝试使用从数据库上下文对象调用的动态SQL存储过程(使用Entity Framework 6.1.1)获取内容,以便填充GridView控件。我无法检索数据。

这是存储过程。这是一个关于存储过程中SQL注入的学生演示,所以我知道这是可注入的,没关系。

ALTER PROCEDURE dbo.SearchProducts
  @SearchTerm VARCHAR(max)
AS
BEGIN
  DECLARE @query VARCHAR(max)
  SET @query = 'SELECT * FROM dbo.Products WHERE Name LIKE ''%' + @SearchTerm + '%'''
  EXEC(@query)
END

我用来执行存储过程的C#代码是:

var db = new MyEntities();
var TEST_SEARCH_TERM = "product";
var result = db.SearchProducts(TEST_SEARCH_TERM);

MyGridView.DataSource = result;
MyGridView.DataBind();

执行时,在Visual Studio的数据库资源管理器中,存储过程正常。但是当在正在运行的ASP.NET应用程序中执行时,我在DataBind()方法中得到一个例外,因为result返回-1而不是IEnumerable DataSet包含由存储过程的SELECT生成的对象。

如何检索数据并填充GridView

4 个答案:

答案 0 :(得分:30)

使用以下步骤解决此问题:

  1. 您需要将存储过程作为函数导入。右键单击实体模型的工作区区域,然后选择Add -> Function Import
  2. 在“添加功能导入”对话框中,输入您希望在模型中引用存储过程的名称,例如Search_Products,从下拉列表中选择您的过程,然后选择过程的返回值从Entities开始,从下拉列表中选择Products
  3. 然后在后面的代码中:

    var db = new MyEntities();
    var TEST_SEARCH_TERM = "product";
    var result = db.Search_Products(TEST_SEARCH_TERM);//Search_Products is the name that you specified in Function Import dialog
    
    MyGridView.DataSource = result;
    MyGridView.DataBind();
    
  4. 您获得-1结果的原因是实体框架无法支持开箱即用的存储过程返回值。我认为对存储过程返回值的支持取决于Entity框架的版本。此外,实体框架没有丰富的存储过程支持,因为它是一个ORM,而不是SQL替代。

答案 1 :(得分:3)

我之前遇到过使用动态SQL的存储过程。如果我添加'SET FMTONLY OFF'这一行,我已成功使用复杂类型(请参阅https://msdn.microsoft.com/en-us/library/ms173839.aspx)到存储过程的顶部,然后再将其添加到EF模型中。使用复杂类型设置模型后,请务必删除此行。

示例:

ALTER PROCEDURE dbo.SearchProducts
  @SearchTerm VARCHAR(max)
AS
BEGIN
  SET FMTONLY OFF;
  DECLARE @query VARCHAR(max)
  SET @query = 'SELECT * FROM dbo.Products WHERE Name LIKE ''%' + @SearchTerm + '%'''
  EXEC(@query)
END

答案 2 :(得分:0)

验证您的EDMX是否具有返回类型: 转到功能导入 - > SearchProducts,然后双击它。

为了使用Complex返回类型,Entity Framework将要求您在存储过程中显式定义列名而不是使用*。

修改存储过程以定义列名称后,可以在项目中更新模型。 (注意,执行完整的SP删除,然后将其添加回您的edmx可能是最佳路径。)

修改

也许你可以修改你的SP,如下所示:

ALTER PROCEDURE dbo.SearchProducts
  @SearchTerm VARCHAR(max)
AS
BEGIN
  SELECT * FROM dbo.Products WHERE Name LIKE '%' + @SearchTerm + '%'
END

答案 3 :(得分:0)

您似乎已经解决了问题,Microsoft的官方文档可从以下链接获得:

如何将存储过程导入实体数据模型: https://msdn.microsoft.com/en-us/library/vstudio/bb896231(v=vs.100).aspx

EF设计师中的复杂类型: https://msdn.microsoft.com/en-gb/data/jj680147.aspx

确保使用最新版本的.net,并在更改数据库时使模型保持最新。