web-dev-qa-db-fra.com

Renvoi d'un DataTable à l'aide d'ExecuteStoreQuery Entity Framework

Je travaille avec un système comportant de nombreuses procédures stockées devant être affichées. La création d'entités pour chacun de mes objets n'est pas pratique. 

Est-ce possible et comment pourrais-je retourner une DataTable en utilisant ExecuteStoreQuery?

public ObjectResult<DataTable> MethodName(string fileSetName) {
using (var dataContext = new DataContext(_connectionString))
{
var returnDataTable = ((IObjectContextAdapter)dataContext).ObjectContext.ExecuteStoreQuery<DataTable>("SP_NAME","SP_PARAM");
return returnDataTable;
}
13
detroitpro

Non, je ne pense pas que cela fonctionnera. Entity Framework est conçu pour renvoyer entités et n'est pas censé renvoyer des objets DataTable.

Si vous avez besoin d'objets DataTable, utilisez straight ADO.NET à la place.

10
marc_s

Oui, c'est possible, mais il devrait être utilisé uniquement pour un jeu de résultats dynamique ou un SQL brut.

public DataTable ExecuteStoreQuery(string commandText, params Object[] parameters)
{
    DataTable retVal = new DataTable();
    retVal = context.ExecuteStoreQuery<DataTable>(commandText, parameters).FirstOrDefault();
    return retVal;
}

Éditer: Il est préférable d’utiliser ADO.NET classique pour obtenir le modèle de données plutôt qu’Entity Framework, car vous ne pourrez probablement pas utiliser DataTable même si vous pouvez exécuter la méthode: context.ExecuteStoreQuery<DataTable>(commandText, parameters).FirstOrDefault();

Exemple ADO.NET:

public DataSet GetResultReport(int questionId)
{
    DataSet retVal = new DataSet();
    EntityConnection entityConn = (EntityConnection)context.Connection;
    SqlConnection sqlConn = (SqlConnection)entityConn.StoreConnection;
    SqlCommand cmdReport = new SqlCommand([YourSpName], sqlConn);
    SqlDataAdapter daReport = new SqlDataAdapter(cmdReport);
    using (cmdReport)
    {
        SqlParameter questionIdPrm = new SqlParameter("QuestionId", questionId);
        cmdReport.CommandType = CommandType.StoredProcedure;
        cmdReport.Parameters.Add(questionIdPrm);
        daReport.Fill(retVal);
    }
    return retVal;
}
15
chuck

Cette méthode utilise la chaîne de connexion du framework d'entités pour établir une connexion ADO.NET, vers une base de données MySQL dans cet exemple.

using MySql.Data.MySqlClient;

public DataSet GetReportSummary( int RecordID )
{
    var context = new catalogEntities();

    DataSet ds = new DataSet();
    using ( MySqlConnection connection = new MySqlConnection( context.Database.Connection.ConnectionString ) )
    {
        using ( MySqlCommand cmd = new MySqlCommand( "ReportSummary", connection ) )
        {
            MySqlDataAdapter adapter = new MySqlDataAdapter( cmd );
            adapter.SelectCommand.CommandType = CommandType.StoredProcedure;
            adapter.SelectCommand.Parameters.Add( new MySqlParameter( "@ID", RecordID ) );
            adapter.Fill( ds );
        }
    }
    return ds;
}
7
jim31415

Oui, cela peut facilement être fait comme ça:

var table = new DataTable();
using (var ctx = new SomeContext())
{
    var cmd = ctx.Database.Connection.CreateCommand();
    cmd.CommandText = "Select Col1, Col2 from SomeTable"; 

    cmd.Connection.Open();
    table.Load(cmd.ExecuteReader());
}
4
CodingYoshi

En règle générale, vous ne devez pas utiliser un DataSet dans une application EF. Mais si vous avez vraiment besoin (par exemple, de créer un rapport), cette solution devrait fonctionner (c'est le code EF 6):

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

Le moyen le plus simple de renvoyer un DataTable à l'aide de EntityFramework consiste à:

MetaTable metaTable = Global.DefaultModel.GetTable("Your EntitySetName");

Par exemple:

MetaTable metaTable = Global.DefaultModel.GetTable("Employees");
2
Polla Tosen

Votre procédure stockée pourrait peut-être renvoyer un type complexe? http://blogs.msdn.com/b/somasegar/archive/2010/01/11/entity-framework-in-net-4.aspx

0
RobbanP