我可以使用Linq投影新的数据类型吗?

时间:2010-03-24 04:13:08

标签: c# .net linq datatable strongly-typed-dataset

我目前有一个csv文件,我正在使用此处的示例进行解析: http://alexreg.wordpress.com/2009/05/03/strongly-typed-csv-reader-in-c/

然后我想循环记录并使用类型化数据集xsd将它们插入Oracle数据库。

这并不困难,例如:

foreach (var csvItem in csvfile)
{
   DataSet.MYTABLEDataTable DT = new DataSet.MYTABLEDataTable();
   DataSet.MYTABLERow row = DT.NewMYTABLERow();
   row.FIELD1 = csvItem.FIELD1;
   row.FIELD2 = csvItem.FIELD2;
}

我想知道如何使用LINQ投影做点什么:

var test = from csvItem in csvfile
  select new MYTABLERow {
    FIELD1 = csvItem.FIELD1,
    FIELD2 = csvItem.FIELD2
}

但是我不认为如果不使用rowbuilder就可以创建这样的数据行,或者可能是数据流的更好的构造函数?

1 个答案:

答案 0 :(得分:2)

可以,但不应该NewRow()是一个方法,而不是允许使用对象初始值设定项的构造函数。为了清晰起见,最好坚持使用foreach循环。

你可以滥用LINQ来解决这个问题,但这是不推荐,仅用于演示目的:

DataTable dt = new DataTable();
dt.Columns.Add("Id", typeof(int));
dt.Columns.Add("Customer", typeof(string));
dt.Rows.Add(new Object[] { 24, "Peter Parker" });
dt.Rows.Add(new Object[] { 42, "Bruce Wayne" });

var query = Enumerable.Range(1, 5).All(i =>
            {
                var row = dt.NewRow();
                row["Id"] = i;
                row[1] = "Customer" + i;
                dt.Rows.Add(row);
                return true;
            });

foreach (DataRow row in dt.Rows)
{
    Console.WriteLine("{0}: {1}", row[0], row[1]);
}

这个想法是使用lambda语句来完成你的工作。请注意,您什么也得不到,而且语句与foreach循环中的语句相同。最重要的是,LINQ是延迟的,因此在迭代查询之前永远不会添加行。在上面的代码片段中,我使用All方法强制立即执行此操作,并为每个项目返回true,以便继续处理所有项目。事实上,var query =位可以删除,因为它没有被使用。

在您的情况下,您的源代码将是csvfile:

csvfile.All(csvItem => { /* do work here */ });

此方法引入了副作用,因为LINQ查询未用于其原始意图。 LINQ用于查询。您可能还会发现Eric Lippert的帖子有用:"foreach" vs "ForEach"