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;
}
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.
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;
}
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;
}
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());
}
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;
}
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");
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