Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用DataContext从LINQ查询填充DataTable的最快方法_C#_Asp.net_Linq_Datatable_Ienumerable - Fatal编程技术网

C# 使用DataContext从LINQ查询填充DataTable的最快方法

C# 使用DataContext从LINQ查询填充DataTable的最快方法,c#,asp.net,linq,datatable,ienumerable,C#,Asp.net,Linq,Datatable,Ienumerable,我正在尝试运行linq查询,但我需要将结果作为datatable,因为我正在使用它将来自不同查询的记录存储在同一viewstate对象中 下面的两个版本编译,但返回一个空集。确切的错误是“值不能为空”。 参数名称:源”。(是的,我已经检查了数据): MyDatabaseDataContext db=新的MyDatabaseDataContext(conn); IEnumerable查询项目= (来自db.STREAM_PROJECTs.AsEnumerable()中的DataRow p) 其中p

我正在尝试运行linq查询,但我需要将结果作为datatable,因为我正在使用它将来自不同查询的记录存储在同一viewstate对象中

下面的两个版本编译,但返回一个空集。确切的错误是“值不能为空”。 参数名称:源”。(是的,我已经检查了数据):

MyDatabaseDataContext db=新的MyDatabaseDataContext(conn);
IEnumerable查询项目=
(来自db.STREAM_PROJECTs.AsEnumerable()中的DataRow p)
其中p.Field(“STREAM_ID”)==StreamID
选择新的
{
项目ID=p.Field(“项目ID”),
项目名称=p.Field(“项目名称”)
})如同数不清的;
DataTable results=queryProjects.CopyToDataTable();

/(来自db.STREAM\u PROJECTs.AsEnumerable()中的p)
//其中p.STREAM_ID==StreamID
//选择新的
//{
//项目名称,
//项目编号
//})如同数不清的;
这里的例子在这种情况下似乎也不起作用

我想我可以用老式的方式运行sql查询命令,但是linq不是应该更快吗?

您的问题是:

as IEnumerable<DataRow>
除非
的版本无法将查询对象(它是
IQueryable
,其中
t
是匿名类型)转换为
IEnumerable
(它不是)时不会引发异常

不幸的是,据我所知,没有一种内置方法可以将具体类型的可枚举项(如本例中的匿名类型)转换为
DataTable
。编写一个不会太复杂,因为您基本上需要以反射方式获取属性,然后迭代集合,并使用这些属性在
数据表中创建列。我将在几分钟后发布一个示例

类似这样的东西,放置在您正在使用的命名空间中的静态类中,应该提供一个扩展方法来实现您想要的功能:

public static DataTable ToDataTable<T>(this IEnumerable<T> source)
{
    PropertyInfo[] properties = typeof(T).GetProperties();

    DataTable output = new DataTable();

    foreach(var prop in properties)
    {
        output.Columns.Add(prop.Name, prop.PropertyType);
    }

    foreach(var item in source)
    {
        DataRow row = output.NewRow();

        foreach(var prop in properties)
        {
            row[prop.Name] = prop.GetValue(item, null);
        }

        output.Rows.Add(row);
    }

    return output;
}
公共静态数据表到数据表(此IEnumerable源)
{
PropertyInfo[]properties=typeof(T).GetProperties();
DataTable输出=新DataTable();
foreach(属性中的var属性)
{
output.Columns.Add(prop.Name,prop.PropertyType);
}
foreach(源中的var项)
{
DataRow行=output.NewRow();
foreach(属性中的var属性)
{
行[prop.Name]=prop.GetValue(项,空);
}
output.Rows.Add(行);
}
返回输出;
}

我明白了-所以它只是隐藏了invalidcastexception?那么我怎样才能把它放到数据表中呢?@JumpingJezza:是的
as
用于您知道对象可能不是您期望的类型并且不是“例外”情况的情况。如果强制转换无效,
as
关键字的计算结果为
null
,并且(因此)只能与引用类型和
null
一起使用。请参阅我刚刚发布的编辑,获取一个示例扩展方法,该方法可以将任何
IEnumerable
转换为
DataTable
。完美!另外,我还发现了一些关于
的新内容(如
:)我必须对可为null的类型进行检查,因为如果类型可为null,output.Columns.Add调用将失败
as IEnumerable<DataRow>
IEnumerable<DataRow> queryProjects = 
    (IEnumerable<DataRow>)(from DataRow p in db.STREAM_PROJECTs.AsEnumerable()
    where p.Field<int>("STREAM_ID") == StreamID
    select new
    {
        PROJECT_ID = p.Field<int>("PROJECT_ID"),
        PROJECT_NAME = p.Field<int>("PROJECT_NAME")
    });
public static DataTable ToDataTable<T>(this IEnumerable<T> source)
{
    PropertyInfo[] properties = typeof(T).GetProperties();

    DataTable output = new DataTable();

    foreach(var prop in properties)
    {
        output.Columns.Add(prop.Name, prop.PropertyType);
    }

    foreach(var item in source)
    {
        DataRow row = output.NewRow();

        foreach(var prop in properties)
        {
            row[prop.Name] = prop.GetValue(item, null);
        }

        output.Rows.Add(row);
    }

    return output;
}