如何在不知道查询结果类型的情况下在 EF/VB.net 中运行存储过程?

Posted

技术标签:

【中文标题】如何在不知道查询结果类型的情况下在 EF/VB.net 中运行存储过程?【英文标题】:How to run a stored procedure in EF/VB.net without knowing the type of the queries result? 【发布时间】:2021-10-08 20:36:08 【问题描述】:

我的应用程序使用 SQL Server 数据库来存储其数据。数据库管理员可以在此数据库中以带参数的存储过程的形式创建任何查询。

这些存储过程又可以由我的应用程序执行。因此,我的应用程序的用户可以使用这些存储过程,而无需直接接触它们。他们在我的应用程序中输入所需的参数,按下一个按钮,然后执行查询(实体框架;Database.SqlQuery)。

但我的应用程序只知道这些存储过程的名称和参数。

现在的问题是我没有返回数据的模型,因为我什至不知道数据库管理员在他的SELECT FROM 语句中使用了哪些数据列。

Database.SqlQuery(Of Object) 不包含任何数据列。

如何在网格中显示来自存储过程的数据列,例如,在不知道数据列本身的情况下?

编辑:它是一个 WPF 应用程序。

【问题讨论】:

你至少应该告诉我们它是什么 - winform 或 webform 应用程序 我相信我有一个类似的 WebForms 应用程序(尽管它是用 C# 编写的)。基本上,在前端 (Run.aspx) 我有一个名为 selectResultsGridView 和一个名为 selectDS 的数据源。然后在后面的代码中,我运行查询,并运行代码selectResults.DataSource = selectDSselectResults.DataBind()。当然,这段代码是用C#编写的,所以它并不直接适用于你的情况,但简短的回答是在页面上制作一个GridView和一个DataSource,然后单击按钮将查询绑定到数据源,并绑定数据源到 GridView。 Serge - 抱歉。它是一个 WPF 应用程序。 没有人必须阅读 cmets 才能理解问题。如果是关于 WPF,请添加适当的标签。 使用数据集和表适配器,这不适用于 EF Core 【参考方案1】:

正如其他人所评论的那样,这种情况对于 EF 来说并不理想,除非您要与 DBA 达成协议,他们将始终只返回特定名称和类型(或一些小的变化)的列然后您无法有效地将它们映射到具有固定属性的对象。如果您将列视为属性,而将属性视为某种对象的固有属性,那么显然这些是不同的日常对象:

Name                    = "John"
Age                     = 23
Weight                  = 220
SocialSecurityNumber    = "ABC123"

Manufacturer        = "Ford"
Model               = "Mustang"
EngineSize          = "6.7"
VIN                 = "1234FM"

你能通过查看道具(而不是值)猜出它们是什么吗?

当然,我们可以说“让我们对它们进行通用映射”,我们将拥有一个对象,然后将属性组合到其中


  Maker          = "Mom & Pop",
  Model          = "John",
  GovtIdentifier = "ABC123",
  Weight         = 220
,

  Maker          = "Ford",
  Model          = "Mustang",
  GovtIdentifier = "1234FM",
  Weight         = 4400
,

..但是没有一个很好的方法来引用所有东西(EngineSize?),你必须继续添加越来越多的道具,如果你不能重用,越来越多的道具将是空的他们..

全力以赴,而不是 EF 的包。 EF 想要实体,每次添加实体时,都需要重新编译和重新发布。


如果结果范围很广,并且从一个查询到下一个查询的名称/类型大不相同,请使用更动态的容器,例如 DataTable:

Dim dt As New DataTable
Using da as New SqlDataAdapter("some_proc_name", "some connection string here")
   da.SelectCommand.CommandType = CommandType.StoredProcedure;
   da.SelectCommand.Parameters.AddWithValue("@a", "whatever") 
   da.Fill(dt);
End Using
myDataGrid.DataContext = dt

..因此您将其分配为自动生成列的网格的数据上下文:

<DataGrid x:Name="myDataGrid" AutoGenerateColumns="True" ItemsSource="Binding">
</DataGrid>

【讨论】:

注意:通常的“addwithvalue is evil”建议并不真正适用于存储过程

以上是关于如何在不知道查询结果类型的情况下在 EF/VB.net 中运行存储过程?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不进行分组的情况下在Oracle中向SQL结果添加虚拟行

BI Answers/OBIEE- 在不影响行结果的情况下在列上创建过滤器

如何在不缩小图像的情况下在 Android 中调整图像大小?

如何在不使用窗口函数的情况下在大查询中选择 max(date)?

如何在不使用 join 或 cte 的情况下在同一查询中使用动态生成的列

如何在不加载页面的情况下在一个页面中加载超过 1500 个产品?