将查询从linq复制到Datatable时出错

时间:2012-09-05 20:55:02

标签: c# linq ienumerable

我刚刚开始处理需要Linq to Sql的项目,并且我能够进行查询和检索数据。但是现在我需要用我正在检索的数据填充DataTable

我的第一个代码如下:

MyDatabase db = new MyDatabase();
var query = from cust in db.Customers
            where cust.CustomerName != "Dante"
            orderby cust.CustomerName
            select new { Name = cust.CustomerName }; 

所以,因为我需要将查询内容复制到Datatable我尝试了this

 IEnumerable<DataRow> query =
    from order in orders.AsEnumerable()
    where order.Field<DateTime>("OrderDate") > new DateTime(2001, 8, 1)
    select order;

// Create a table from the query.
DataTable boundTable = query.CopyToDataTable<DataRow>();

然后,我的代码如下所示:

IEnumerable<DataRow> myQuery = from cust in db.Customers.AsEnumerable()
                    where cust.Name != "Dante"
                    orderby cust.Name
                    select new { Name = cust.Name };

DataTable myDataTable = myQuery.CopyToDataTable<DataRow>();

但是使用此代码,编译器会引发错误:

Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<AnonymousType#1>' to 'System.Collections.Generic.IEnumerable<System.Data.DataRow>

select字出现错误。

所以,我做错了什么?我该怎么做才能避免这种转换问题?

希望有人可以帮助我,提前谢谢。

3 个答案:

答案 0 :(得分:3)

问题正如错误所述;你的“select”子句正在创建一个匿名类型的实例,其中包含一个成员“Name”。此匿名类型不是也不能是DataRow,因此查询生成的内容与您要将其设置为的变量之间的隐式转换失败。

相反,您应该接受此查询,并且对于它返回的匿名类型的每个元素,将该值添加为DataTable的新DataRow。您不能只从头开始创建新的DataRow; DataRow类需要一个上下文,即父DataTable,来定义DataRow应该具有的列。

答案 1 :(得分:3)

有一种方法可以从DataTable以外的结果中创建IEnumerable<DataRow>,但它很复杂。 Implement CopyToDataTable Where the Generic Type T Is Not a DataRow

但是,对于您的情况,我建议您按照以下方式进行操作。返回原始查询:

MyDatabase db = new MyDatabase();
var query = from cust in db.Customers
            where cust.CustomerName != "Dante"
            orderby cust.CustomerName
            select new { Name = cust.CustomerName };

然后定义您的单个字段DataTable,因为当您最终创建DataRow时,它需要一个架构来工作:

DataTable myDataTable = new DataTable();
myDataTable.Columns.Add(
    new DataColumn()
    {
        DataType = System.Type.GetType("System.String"),
        ColumnName = "Name"
    }
);

最后,浏览查询结果并手动将DataRows添加到DataTable

foreach (var element in query)
{
    var row = myDataTable.NewRow();
    row["Name"] = element.Name;
    myDataTable.Rows.Add(row);
}

答案 2 :(得分:1)

我猜这个

var myQuery = from cust in db.Customers.AsEnumerable()
                    where cust.Name != "Dante"
                    orderby cust.Name
                    select new { Name = cust.Name };

或试试这个

 string[] myQuery = db.Customers.Rows
                       .Cast<DataRow>()
                       .Where(r=>r.Name!="Dante")
                       .Orderby(r=>r.Name)
                       .Select(r=>r.Field<string>("Name"))
                       .ToArray()