首页 / Entity Framework / 正文

[Entity Framework].NET/C#应用程序编程开发中如何使用Entity Framework返回DataTable数据表?

2697 发布于: 2018-06-11 读完约需13分钟

问题描述

在.NET/C#的应用程序编程开发中,有一个特殊的实现需求:在使用 Entity Framework 的情况下,需要调用一个存储过程,存储过程的编码包含了很多SQL语句,现在需要使用 Entity Framework调用这个存储过程,并使用DataTable获取这个存储过程返回的结果集,以下是一部分伪代码的实现,如下:

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));
    // 需要将存储过程返回的结果集放到DataTable中

}

那么,完整的 Entity Framework获取 DataTable的实现应该如何写呢?

方案一

使用 Entity Framework 中的上下文获取一个数据库的连接,然后使用 SqlCommandExecuteReader()方法获取到DataReader,最后,使用DataTableRead()方法将DataReader中的数据填充到DataTable中,具体的实现代码如下:

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)
    {
        throw;
    }
    finally
    {
        if (connectionState != ConnectionState.Closed) conn.Close();
    }
    return dt;
}

方案二

使用LINQ TO SQL来处理,以下实现将使用Entity Framework返回一个DataTable,如下:

DataTable dt = new DataTable();
(from rec in database.Table.AsEnumerable()
                     select new
                     {
                         id = rec.id,
                         name = rec.Name
                         //其他字段
                     }).Aggregate(table, (dt, r) =>
                     {
                         dt.Rows.Add(r.id, r.Name);
                         return dt;
                     });

特别说明: 使用以上实现方案时,请注意数据的筛选条件,否则在大数据量情况下将会是个问题。

方案三

另一种简单,快速实现的静态扩展方法,使用了 DbProviderFactoriesCreateDataAdapter() 方法,如下:

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

调用示例:

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

方案四

一个支持自定义SQL语句和任意参数的方法封装,如下:

DataSet GetDataSet(string sql, CommandType commandType, Dictionary<string, Object> parameters)
    {
        var result = new DataSet();

        using (var context = new MyDbContext())
        {
            var cmd = context.Database.Connection.CreateCommand();
            cmd.CommandType = commandType;
            cmd.CommandText = sql;

            foreach (var pr in parameters)
            {
                var p = cmd.CreateParameter();
                p.ParameterName = pr.Key;
                p.Value = pr.Value;
                cmd.Parameters.Add(p);
            }

            try
            {
                context.Database.Connection.Open();
                var reader = cmd.ExecuteReader();

                do
                {
                    var tb = new DataTable();
                    tb.Load(reader);
                    result.Tables.Add(tb);

                } while (!reader.IsClosed);
            }
            finally
            {
                context.Database.Connection.Close();
            }
        }

        return result;
    }

版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。

上一篇: [Javascript]Javascript编程开发中如何使用jQuery获取$(this)选择器的子节点?

下一篇: [Entity Framework].NET/C#应用程序编程开发中如何使用Entity Framework快速删除指定表的所有数据记录?

本文永久链接码友网 » [Entity Framework].NET/C#应用程序编程开发中如何使用Entity Framework返回DataTable数据表?

分享扩散:

发表评论

登录用户才能发表评论, 请 登 录 或者 注册