Как запустить хранимую процедуру в EF/VB.net, не зная типа результата запросов?

#sql-server #wpf #vb.net #entity-framework #stored-procedures

Вопрос:

Мое приложение использует базу данных SQL Server для хранения своих данных. Администратор базы данных может создавать любые запросы в этой базе данных в виде хранимых процедур с параметрами.

Эти хранимые процедуры, в свою очередь, могут быть выполнены моим приложением. Таким образом, пользователи моего приложения могут использовать эти хранимые процедуры, не вступая с ними в прямой контакт. Они вводят необходимые параметры в мое приложение, нажимают кнопку, после чего выполняется запрос (Entity Framework; Database.SqlQuery ).

Но все, что мое приложение знает об этих хранимых процедурах, — это их имя и их параметры.

Проблема сейчас в том, что у меня нет модели для возврата данных, так как я даже не знаю, какие столбцы данных использует администратор базы данных в своем SELECT FROM заявлении.

Database.SqlQuery(Of Object) не содержит никаких столбцов данных.

Как я могу отобразить столбцы данных из хранимой процедуры в сетке, например, не зная самих столбцов данных?

ИЗМЕНИТЬ: это приложение WPF.

Комментарии:

1. Вы должны хотя бы сказать нам, что это такое — winform или приложение webform

2. Я полагаю, что у меня есть аналогичное приложение WebForms (хотя оно на C#). В основном, на переднем конце (Run.aspx) У меня есть GridView вызываемый selectResults и вызываемый источник данных selectDS . Затем в коде позади я запускаю запрос, и запускаю код selectResults.DataSource = selectDS , и selectResults.DataBind() . Конечно, этот код написан на C#, поэтому он напрямую не применим к вашей ситуации, но короткий ответ-создайте представление сетки и источник данных на странице, а затем нажмите кнопку «Привязать запрос к источнику данных» и свяжите источник данных с представлением сетки.

3. Серж — прости. Это приложение WPF.

4. Никто не должен читать комментарии, чтобы понять вопрос. Если речь идет о WPF, добавьте соответствующий тег.

5. Используйте набор данных и адаптер таблицы, это неприменимо для EF Core

Ответ №1:

Как отмечали другие, эта ситуация на самом деле не идеальна для EF, если вы не собираетесь заключать сделку с администратором базы данных, что они всегда будут возвращать только столбцы определенного имени и типа (или некоторые небольшие вариации), тогда вы не сможете эффективно сопоставлять их с объектами, которые имеют фиксированные свойства. Если вы рассматриваете столбцы как свойства, а свойства как неотъемлемые от определенного вида объекта, то очевидно, что это разные повседневные объекты:

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

И

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

Можете ли вы догадаться, что это такое, просто взглянув на реквизит (а не на значения)?

Конечно, мы могли бы сказать: «Давайте сопоставим их в общем виде», у нас будет один объект, и мы внесем в него свойства

 {
  Maker          = "Mom amp; Pop",
  Model          = "John",
  GovtIdentifier = "ABC123",
  Weight         = 220
},
{
  Maker          = "Ford",
  Model          = "Mustang",
  GovtIdentifier = "1234FM",
  Weight         = 4400
},
 

..но на самом деле нет действительно хорошего способа ссылаться на все (размеры двигателя?), И вам нужно продолжать добавлять все больше и больше реквизитов, все больше и больше которых будут пустыми, если вы не сможете их повторно использовать..

Все в сборе, только не в сумке ЭФ. 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
 

..таким образом, вы назначаете его в качестве datacontext сетки, которая автоматически генерирует столбцы:

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

Комментарии:

1. Примечание: обычный совет «addwithvalue-это зло» на самом деле не относится к sprocs