C# 将存储过程LINQ结果列表转换为数据表
我正在修改一些工作代码,将一些代码转换为使用LINQ调用存储过程。这使C#在很大程度上看起来更整洁 当前代码调用存储过程来创建数据表,然后将数据表发送到openxml以创建excel电子表格供下载。这种方法有效 我想修改它以从LINQ调用SP。 我从LINQ调用一个存储过程来获取一个列表。但是,openxml需要一个数据表 我的代码如下所示:C# 将存储过程LINQ结果列表转换为数据表,c#,linq,stored-procedures,datatable,C#,Linq,Stored Procedures,Datatable,我正在修改一些工作代码,将一些代码转换为使用LINQ调用存储过程。这使C#在很大程度上看起来更整洁 当前代码调用存储过程来创建数据表,然后将数据表发送到openxml以创建excel电子表格供下载。这种方法有效 我想修改它以从LINQ调用SP。 我从LINQ调用一个存储过程来获取一个列表。但是,openxml需要一个数据表 我的代码如下所示: using (TEMPDataContext dbc = new TEMPDataContext(connectionString)) { Get
using (TEMPDataContext dbc = new TEMPDataContext(connectionString))
{
GetTestPlanquestionnaireResult tq = (GetTestPlanquestionnaireResult) dbc.GetTestPlanquestionnaire(tbStartDate.Text, tbEndDate.Text);
DataTable tbl = tq.ConvertToDataTable();
MemoryStream ms = new MemoryStream();
using (ExcelPackage pck = new ExcelPackage(ms))
{
ExcelWorksheet ws = pck.Workbook.Worksheets.Add("Results");
ws.Cells["A1"].LoadFromDataTable(tbl, true);
ws.Cells[1, 1, 1, tbl.Columns.Count].Style.Font.Bold = true;
ws.Cells[1, 1, 1, tbl.Columns.Count].AutoFitColumns();
pck.Save();
}
byte[] buffer = ms.ToArray();
Context.Response.ClearContent();
Context.Response.AddHeader("content-disposition", "attachment; filename=\"downloadfilename.xlsx\"");
Context.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Context.Response.OutputStream.Write(buffer, 0, buffer.Length);
Context.Response.End();
}
我的问题是代码中调用尚不存在的方法的那一行;即DataTable tbl=tq.ConvertToDataTable()代码>
我还没有为ConvertToDataTable()
编写任何代码,因为我无法想象还没有什么东西可以做到这一点。如果这就是恼怒的程度,那么我可能会保持原样,不担心转换成LINQ。有没有一种简单易读的方法可以做到这一点?如果您仍然感兴趣,这是我的LINQPad扩展文件:
public static DataTable AsDataTable<T>(this IEnumerable<T> rows) {
var dt = new DataTable();
var infos = typeof(T).GetProperties();
foreach (var info in infos)
dt.Columns.Add(new DataColumn(info.Name, info.PropertyType));
foreach (var r in rows) {
var nr = dt.NewRow();
for (int i = 0; i < infos.Length; ++i) {
nr[i] = infos[i].GetValue(r);
}
dt.Rows.Add(nr);
}
return dt;
}
public static EnumerableRowCollection<DataRow> AsDataRows<T>(this IEnumerable<T> rows) => rows.AsDataTable().AsEnumerable();
公共静态数据表AsDataTable(此IEnumerable行){
var dt=新数据表();
var infos=typeof(T).GetProperties();
foreach(信息中的var信息)
添加(新数据列(info.Name,info.PropertyType));
foreach(行中的var r){
var nr=dt.NewRow();
对于(int i=0;irows.AsDataTable().AsEnumerable();
如果您仍然感兴趣,这是我的LINQPad扩展文件:
public static DataTable AsDataTable<T>(this IEnumerable<T> rows) {
var dt = new DataTable();
var infos = typeof(T).GetProperties();
foreach (var info in infos)
dt.Columns.Add(new DataColumn(info.Name, info.PropertyType));
foreach (var r in rows) {
var nr = dt.NewRow();
for (int i = 0; i < infos.Length; ++i) {
nr[i] = infos[i].GetValue(r);
}
dt.Rows.Add(nr);
}
return dt;
}
public static EnumerableRowCollection<DataRow> AsDataRows<T>(this IEnumerable<T> rows) => rows.AsDataTable().AsEnumerable();
公共静态数据表AsDataTable(此IEnumerable行){
var dt=新数据表();
var infos=typeof(T).GetProperties();
foreach(信息中的var信息)
添加(新数据列(info.Name,info.PropertyType));
foreach(行中的var r){
var nr=dt.NewRow();
对于(int i=0;irows.AsDataTable().AsEnumerable();
并非所有列表都是平面对象的集合,因此,为datatable功能提供框架是没有意义的。我个人不会麻烦使用EF调用存储过程,将其与您对DataTable的需求结合起来,我建议您保持原样。非常好。这听起来是正确的答案。您可以轻松地将简单对象转换为带有反射的datatable,但我看不出这有什么好处。SqlDataAdapter可以完全独立地将结果读入datatable。这与openXML无关。并非所有列表都是平面对象的集合,因此为datatable功能提供框架是没有意义的。我个人不会麻烦使用EF调用存储过程,将其与您对DataTable的需求结合起来,我建议您保持原样。非常好。这听起来是正确的答案。您可以轻松地将简单对象转换为带有反射的datatable,但我看不出这有什么好处。SqlDataAdapter可以完全独立地将结果读入datatable。这与openXML无关。为什么不使用AsDataTable(此IEnumerable行)
?然后可以用typeof(T)
替换难看的行.First().GetType()
。为什么不将设为数据表(此IEnumerable行)
?然后可以用typeof(T)
替换难看的行.First().GetType()
。