我正在使用一个需要显示许多存储过程的系统。为每个对象创建实体是不实际的。
是否可以,如何使用DataTable
返回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;
}
答案 0 :(得分:16)
是的,但它应该只用于动态结果集或原始SQL。
public DataTable ExecuteStoreQuery(string commandText, params Object[] parameters)
{
DataTable retVal = new DataTable();
retVal = context.ExecuteStoreQuery<DataTable>(commandText, parameters).FirstOrDefault();
return retVal;
}
编辑:最好使用经典的ADO.NET来获取数据模型而不是使用实体框架,因为即使您可以运行该方法,也很可能无法使用DataTable
:context.ExecuteStoreQuery<DataTable>(commandText, parameters).FirstOrDefault();
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;
}
答案 1 :(得分:10)
不,我认为这不会起作用 - 实体框架主要用于返回实体,而不是要返回DataTable
个对象。
如果您需要DataTable
个对象,请改用直接的ADO.NET。
答案 2 :(得分:7)
此方法使用实体框架中的连接字符串建立ADO.NET连接,在此示例中为MySQL数据库。
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;
}
答案 3 :(得分:5)
是的,可以这样轻松地完成:
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 :(得分:4)
根据规则,您不应在EF应用程序中使用DataSet。但是,如果你真的需要(例如,提供报告),该解决方案应该有效(它是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;
}
答案 5 :(得分:2)
使用EntityFramework返回DataTable的最简单方法是执行以下操作:
MetaTable metaTable = Global.DefaultModel.GetTable("Your EntitySetName");
例如:
MetaTable metaTable = Global.DefaultModel.GetTable("Employees");
答案 6 :(得分:0)
也许你的存储过程可以返回一个复杂的类型? http://blogs.msdn.com/b/somasegar/archive/2010/01/11/entity-framework-in-net-4.aspx
答案 7 :(得分:0)
在我的基于实体框架的解决方案中,我需要用sql替换我的一个Linq查询 - 出于效率原因。
此外,我希望我的结果来自一个存储过程的DataTable
,以便我可以创建一个表值参数以传递到第二个存储过程。所以:
我使用sql
我不想要DataSet
出于效率原因,迭代IEnumerable
可能不会削减它
此外,我使用的是EF6,因此我希望DbContext.SqlQuery
超过ObjectContext.ExecuteStoreQuery
原始广告要求。
然而,我发现这不起作用:
_Context.Database.SqlQuery<DataTable>(sql, parameters).FirstOrDefault();
这是我的解决方案。它返回使用ADO.NET DataTable
获取的SqlDataReader
- 我认为它比只读数据上的SqlDataAdapter
更快。它并没有严格回答这个问题,因为它使用的是ADO.Net,但它显示了在从DbContext
protected DataTable GetDataTable(string sql, params object[] parameters)
{
//didn't work - table had no columns or rows
//return Context.Database.SqlQuery<DataTable>(sql, parameters).FirstOrDefault();
DataTable result = new DataTable();
SqlConnection conn = Context.Database.Connection as SqlConnection;
if(conn == null)
{
throw new InvalidCastException("SqlConnection is invalid for this database");
}
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddRange(parameters);
conn.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
result.Load(reader);
}
return result;
}
}