web-dev-qa-db-fra.com

Retour de table de données à l'aide d'un framework d'entité

J'utilise le framework d'entité. Il y a une situation particulière dans mon application où je dois utiliser une procédure stockée. Puisqu'il y a beaucoup d'instructions SQL écrites dans le SP, je ne veux pas le réécrire dans mon code C #. J'ai seulement besoin de récupérer le résultat sous la forme d'une table de données. J'ai écrit un peu de code mais je suis bloqué à un moment donné. Quelqu'un peut-il compléter le code ci-dessous?

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.
}
12
user1640256

Merci beaucoup les gars. Je l'ai résolu. Voici la solution:

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;
}
17
user1640256

Cet exemple renvoie un objet datatable sélectionnant des données dans EntityFramework.

Je pense que c'est la meilleure solution pour atteindre cet objectif. Cependant, le problème avec cette solution est que chaque enregistrement est énuméré. Vous voudrez peut-être filtrer la liste d'abord, puis l'exécuter à partir de la liste pour éviter cela.

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;
                     });
8
John Smith

Cette solution est simple, très rapide et facile à utiliser.

Créez une extension 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;
            }
        }
    }
}

Exemples:

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()
                    );
}
4
F.Sighinolfi

Amélioration de la solution précédente, incluant désormais des paramètres génériques (non spécifiques à SQL Server) et la prise en charge de plusieurs jeux de résultats:

    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;
    }
1
Daniel Brilho