18

我正在使用具有许多需要显示的存储过程的系统。为我的每个对象创建实体是不切实际的。

是否有可能,我将如何返回DataTableusing 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;
}
4

8 回答 8

18

是的,这是可能的,但它应该仅用于动态结果集或原始 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;
}
于 2012-07-02T11:03:44.700 回答
12

不,我认为这行不通 - 实体框架旨在返回实体,并不意味着返回DataTable对象。

如果您需要DataTable对象,请直接使用 ADO.NET。

于 2011-01-03T17:45:59.140 回答
8

此方法使用实体框架中的连接字符串来建立 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;
}
于 2013-10-11T18:00:10.347 回答
7

是的,它可以像这样轻松完成:

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());
}
于 2017-12-05T18:28:21.740 回答
5

根据规则,您不应在 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;
    }
于 2016-02-24T17:04:22.897 回答
3

在我的基于实体框架的解决方案中,出于效率原因,我需要用 sql 替换我的 Linq 查询之一。此外,我希望我的结果DataTable来自一个存储过程,以便我可以创建一个表值参数以传递给第二个存储过程。所以:

  1. 我正在使用 sql

  2. 我不想要一个DataSet

  3. 迭代一个IEnumerable可能不会削减它 - 出于效率原因

另外,我使用的是 EF6,所以我更愿意按照原始海报的要求DbContext.SqlQueryObjectContext.ExecuteStoreQuery

但是,我发现这不起作用:

_Context.Database.SqlQuery<DataTable>(sql, parameters).FirstOrDefault();

这是我的解决方案。它返回DataTable使用 ADO.NET 获取的a SqlDataReader- 我相信它比SqlDataAdapter只读数据上的 a 更快。它没有严格回答这个问题,因为它使用 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;
        }
    }
于 2017-05-18T10:28:53.847 回答
1

使用 EntityFramework 返回 DataTable 的最简单方法是执行以下操作:

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

例如:

MetaTable metaTable = Global.DefaultModel.GetTable("Employees");
于 2011-07-12T11:45:44.550 回答
0

也许您的存储过程可以返回一个复杂的类型? http://blogs.msdn.com/b/somasegar/archive/2010/01/11/entity-framework-in-net-4.aspx

于 2011-01-03T18:00:44.707 回答