问题描述
在.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
中的上下文获取一个数据库的连接,然后使用 SqlCommand
的ExecuteReader()
方法获取到DataReader
,最后,使用DataTable
的Read()
方法将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;
});
特别说明: 使用以上实现方案时,请注意数据的筛选条件,否则在大数据量情况下将会是个问题。
方案三
另一种简单,快速实现的静态扩展方法,使用了 DbProviderFactories
和 CreateDataAdapter()
方法,如下:
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;
}
版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。
发表评论
登录用户才能发表评论, 请 登 录 或者 注册