【问题标题】:Converting a stored procedure LINQ result list to a DataTable将存储过程 LINQ 结果列表转换为 DataTable
【发布时间】:2017-07-20 20:18:29
【问题描述】:

我正在修改一些工作代码以将一些代码转换为使用 LINQ 调用存储过程。它使 C# 在很大程度上看起来更整洁。

此当前代码调用存储过程来创建数据表,然后将其发送到 openxml 以创建 Excel 电子表格以供下载。这种方法有效。

我想修改它以从 LINQ 调用 SP。 我正在从 LINQ 调用存储过程来获取列表。但是,openxml 需要一个 DataTable。

我的代码如下所示:

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。有没有一种简单易读的方法来做到这一点?

【问题讨论】:

  • 并非所有列表都是平面对象的集合,因此框架提供的列表到数据表功能没有意义。我个人不会费心使用 EF 调用存储过程,再加上您对 DataTable 的需求,我建议保持原样。
  • 非常好。这听起来是正确的答案。
  • 您可以通过反射轻松地将简单对象转换为数据表,但我认为这里没有优势。 SqlDataAdapter 可以完全自行将结果读入数据表。
  • 这与openXML无关。

标签: c# linq stored-procedures datatable


【解决方案1】:

如果您仍然感兴趣,这是来自我的 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&lt;T&gt;(this IEnumerable&lt;T&gt; rows)?然后你可以用typeof(T)代替丑陋的rows.First().GetType()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-10
  • 2013-10-22
相关资源
最近更新 更多