2014-05-16 2 views
6

Я использую структуру сущности. В моем приложении есть одна конкретная ситуация, когда я должен использовать хранимую процедуру. Поскольку в SP много инструкций SQL, я не хочу переписывать их в свой код на C#. Мне нужно вернуть результат только в виде данных. Я написал немного кода, но я застрял в какой-то момент. Может ли кто-нибудь заполнить код ниже?Возвращение данных с использованием структуры сущности

using (dbContext.Database.Connection) 
{ 
dbContext.Database.Connection.Open(); 
DbCommand cmdItems= dbContext.Database.Connection.CreateCommand(); 
cmdItems.CommandText = "GetAvailableItems"; 
cmdItems.CommandType = CommandType.StoredProcedure; 
cmdItems.Parameters.Add(new SqlParameter("jobCardId", 100525)); 
//Need to write code below to populate a DataTable. 
} 
+0

использование упоминается ссылка http://www.entityframeworktutorial.net/EntityFramework4.3/execute-stored-procedure-using-dbcontext .aspx –

+0

Сначала я использую код, и у меня нет объекта для возвращаемого набора данных. Мне нужен результирующий набор как DataTable. Вот где мне нужно выполнить операцию над динамическими данными (данные с разными именами столбцов для переданного параметра). – user1640256

+0

@ user1640256 Я вижу из кода, что вы «получаете» что-то из базы данных. Я делаю вывод, что вы выполняете запрос SELECT. Значит, вы хорошо знаете, какие столбцы вы извлекаете из БД. Можете ли вы просто создать объект и сопоставить результаты хранимой процедуры с сущностью. Это должно сделать вашу работу довольно простой. –

ответ

9

Большое спасибо, ребята. Я решил это. Вот решение:

using (var context = new DataBaseContext()) 
{ 
    var dt = new DataTable(); 
    var conn = context.Database.Connection; 
    var connectionState = conn.State; 
    try 
    { 
     if (connectionState != ConnectionState.Open) conn.Open(); 
     using (var cmd = conn.CreateCommand()) 
     { 
      cmd.CommandText = "GetAvailableItems"; 
      cmd.CommandType = CommandType.StoredProcedure; 
      cmd.Parameters.Add(new SqlParameter("jobCardId", 100525)); 
      using (var reader = cmd.ExecuteReader()) 
      { 
       dt.Load(reader); 
      } 
     } 
    } 
    catch (Exception ex) 
    { 
     // error handling 
     throw; 
    } 
    finally 
    { 
     if (connectionState != ConnectionState.Closed) conn.Close(); 
    } 
    return dt; 
} 
+1

Вот почему я проигнорировал это: это не использует сущность, фактически обходит сущность, используя традиционный sql. Эта муха перед лицом сущности, которая должна поддерживать состояние между базой данных и локальными данными. –

+1

Там _are_ используются для этого, хотя ... Подумайте о устаревшем приложении, где нужно повторно использовать db, но записывается новый код (что я сейчас делаю). EF можно работать во многих местах, что облегчает жизнь, но есть некоторые устаревшие sprocs, которые возвращают разные столбцы (сводные таблицы). Я не знаю, как это сопоставить с Entity, когда имена столбцов являются динамическими. Так уверен. Не "EF-friendly" ... но иногда необходимость в реальной жизни – BLSully

+1

Re: Есть варианты использования. Конечно. Но, обращаясь к вопросу, который был «Возврат данных с использованием структуры сущностей», это плохой ответ. Кроме того, в целом, если вы не в таком исключении, как вы упомянули, это не хороший код для людей, с которыми можно работать. См. Мой ответ ниже. –

6

В этом примере будет возвращать данные на выбирающий datatable объекта из EntityFramework.

Я считаю, что это лучшее решение для цели. Однако проблема с этим решением заключается в том, что каждая запись перечисляется. Возможно, вы захотите выбрать фильтр, а затем запустите его из списка, чтобы этого избежать.

DataTable dt = new DataTable(); 
(from rec in database.Table.AsEnumerable() 
        select new 
        { 
         id = rec.id, 
         name = rec.Name 
         //etc 
        }).Aggregate(table, (dt, r) => 
        { 
         dt.Rows.Add(r.id, r.Name); 
         return dt; 
        }); 
+0

Спасибо, John, я искал способ, который фактически использует Entity Framework. –

+0

Это прекрасно, но это совсем не ответит на этот конкретный вопрос. В вашем ответе здесь есть 'datbase.Table'. Вы работаете с сущностью в своем случае, тогда как вопрос связан с данными, которые неизвестны. С помощью DataTable вы можете наблюдать возвращаемый набор данных, включая его количество столбцов и имена. И, конечно же, данные. Если вы используете E.F. и Entities, в основном LinqToSQL или LinqToEntities, среди тысяч строк кода, но имеют ОДИН экземпляр, где вам нужен DataTable для наблюдения за неизвестным набором данных, ваш ответ вообще не работает. – Suamere

1

Просто улучшение предыдущего решения, в настоящее время, включая общие параметры (не SQL Server) и конкретный Mutiple результирующей поддержки:

DataSet GetDataSet(string sql, CommandType commandType, Dictionary<string, Object> parameters) 
    { 
     // creates resulting dataset 
     var result = new DataSet(); 

     // creates a data access context (DbContext descendant) 
     using (var context = new MyDbContext()) 
     { 
      // creates a Command 
      var cmd = context.Database.Connection.CreateCommand(); 
      cmd.CommandType = commandType; 
      cmd.CommandText = sql; 

      // adds all parameters 
      foreach (var pr in parameters) 
      { 
       var p = cmd.CreateParameter(); 
       p.ParameterName = pr.Key; 
       p.Value = pr.Value; 
       cmd.Parameters.Add(p); 
      } 

      try 
      { 
       // executes 
       context.Database.Connection.Open(); 
       var reader = cmd.ExecuteReader(); 

       // loop through all resultsets (considering that it's possible to have more than one) 
       do 
       { 
        // loads the DataTable (schema will be fetch automatically) 
        var tb = new DataTable(); 
        tb.Load(reader); 
        result.Tables.Add(tb); 

       } while (!reader.IsClosed); 
      } 
      finally 
      { 
       // closes the connection 
       context.Database.Connection.Close(); 
      } 
     } 

     // returns the DataSet 
     return result; 
    } 
+2

Вы копируете и вставляете этот ответ на несколько вопросов ([1] (http://stackoverflow.com/a/35608488/189134), [2] (http://stackoverflow.com/a/35608325/189134)) , Пожалуйста остановись. Ответы не предназначены для захоронения одного и того же блока текста снова и снова. Вместо этого сосредоточьтесь на вопросе и ответьте на то, что задают. Длинный блок текста этого не делает. – Andy

2

Это решение очень простое, очень быстрое и простое в использовании.

Создать расширение DbContext:

using System.Data; 
using System.Data.Common; 
using System.Data.Entity; 
.. 
.. 
public static class DbContextExtensions 
{ 
    public static DataTable DataTable(this DbContext context, string sqlQuery) 
    { 
     DbProviderFactory dbFactory = DbProviderFactories.GetFactory(context.Database.Connection); 

     using (var cmd = dbFactory.CreateCommand()) 
     { 
      cmd.Connection = context.Database.Connection; 
      cmd.CommandType = CommandType.Text; 
      cmd.CommandText = sqlQuery; 
      using (DbDataAdapter adapter = dbFactory.CreateDataAdapter()) 
      { 
       adapter.SelectCommand = cmd; 

       DataTable dt = new DataTable(); 
       adapter.Fill(dt); 

       return dt; 
      } 
     } 
    } 
} 

Примеры:

using (MyDbContext db = new MyDbContext()) 
{ 
    string query = db.Students.Where(o => o.Age > 20).ToString(); 

    DataTable dataTable = db.DataTable(query); 

    .. 

    DataTable dt = db.DataTable(
         ( from o in db.Studets 
          where o.Age > 20 
          select o 
         ).ToString() 
        ); 
} 
Смежные вопросы