繁体   English   中英

使用Linq在不带where子句的DataTable上执行Select语句

[英]Select statement on DataTable without where clause using Linq

我有一段代码需要处理一个DataTable。 DataTable看起来像这样:

  PartnerID    |    Partner Name    |    GroupID    |    Group Name    |    Description
------------------------------------------------------------------------------------------
      1        |     First Name     |       4       |    Group Name1   |   Foo
      2        |     Second Name    |       12      |    Group Name2   |    Bar
      3        |     Third Name     |       7       |    Group Name3   |    Hello
      3        |     Third Name     |       8       |    Group Name4   |    Hello World

现在我要完成的是以下SQL语句的性能:

SELECT DISTINCT PartnerID, Partner Name
FROM Table1

在使用Linq的C#中,预期输出如下所示:

  PartnerID    |    Partner Name    |
-------------------------------------
      1        |    First Name      |
      2        |    Second Name     |
      3        |    Third Name      |

我已经看过以下帖子:

数据表上的LINQ查询

并发现这对我的情况无济于事,因为我真正想要做的就是获取指定的列,但是那里的所有答案都显示了一个解决方案,该解决方案似乎只在处理where语句或默认情况下选择所有列。

我当前的代码现在看起来像这样:

     static void Main(string[] args)
     {
        DataTable fullTable = new DataTable();

        AddColumns(fullTable, "PartnerID", "Partner Name", "GroupID", "Group Name", "Description");

        fullTable.Rows.Add(1, "First Name", 4, "Group Name1", "Foo");
        fullTable.Rows.Add(2, "Second Name", 12, "Group Name2", "Bar");
        fullTable.Rows.Add(3, "Third Name", 7, "Group Name3", "Hello");
        fullTable.Rows.Add(3, "Third Name", 8, "Group Name4", "Hello World");

        var selectTwoCols = from arow in fullTable.AsEnumerable()
                            select arow; //how do i select specific columns from those rows?
        foreach (DataRow dataRow in selectTwoCols.Rows)
        {
            foreach (var item in dataRow.ItemArray)
            {
                Console.Write(item + " ");
            }
            Console.WriteLine();
        }

    }

    static void AddColumns(DataTable table, params string[] columnNames)
    {
        for (int i = 0; i < columnNames.Length; i++)
        {
            table.Columns.Add(columnNames[i]);
        }
    }

我也愿意使用不同的类,尽管我仍然很想知道如何使用DataTables来解决这个问题。

fullTable
   .AsEnumerable()
   .Select(x => new 
                { 
                   PartnerID = x.Field<int>("PartnerID"), 
                   PartnerName = x.Field<string>("Partner Name")
                })
   .Distinct();

这将创建一个具有所需两个属性的匿名类型。 然后您将应用Distinct删除重复项。 匿名类型为您处理GetHashCodeEqualsDistinct用于标识重复项。

我们已经在这里得到了很好的答案,但是我认为这是一种更“预期”的方式。

除了DataTable类之外,C#还提供一个DataView类。

在该类文档中,我们可以阅读以下内容:

表示用于排序,过滤,搜索,编辑和导航的DataTable的可绑定数据的自定义视图。

因此,从这一点来看,我假设Microsoft打算将此类与DataTable结合使用,以过滤掉行或列以及文档中提到的几乎所有操作。

所以我用

DataView view = new DataView(fullTable); 

DataTable twoColsDistinct = view.ToTable(true, "PartnerID", "Partner Name"); //distinct
DataTable twoColsNonDistinct = view.ToTable(false, "PartnerID", "Partner Name"); //not distinct

要获得仅选择了两个必需列的两个DataTables并打印这两个datatables的内容,将导致以下输出:

two cols distinct
----------------------
1 First Name
2 Second Name
3 Third Name
----------------------
two cols non distinct
----------------------
1 First Name
2 Second Name
3 Third Name
3 Third Name

这正是我所需要的。 只是选择列。

使用以下代码可得到完全相同的输出:

var query = fullTable
               .AsEnumerable()
               .Select(x => new
                   {
                       PartnerID = x.Field<string>("PartnerID"),
                       PartnerName = x.Field<string>("Partner Name")
                   }
               ).Distinct();

foreach(var t in query)
{
    Console.WriteLine(t.PartnerID + " " + t.PartnerName);
}

版画

1 First Name
2 Second Name
3 Third Name

尽管我个人更喜欢上面的更紧凑的解决方案,因为使用“更长的”解决方案,我们正在创建自定义对象(更精确地:匿名类型),而PartnerID和PartnerName成为对象实例变量,而在我的“简单”情况下,我不是首先处理任何面向对象的“东西”。

我发现紧凑的解决方案更易于阅读和理解。

奖金:

我们可以使用同一个DataView对象来创建过滤后的DataTable,这可能有用也可能没有用:

view.RowFilter = "PartnerID > 1";

DataTable partnerIdGreaterThanOne = view.ToTable(true);

打印此数据表将输出以下内容:

2 Second Name 12 Group Name2 Bar
3 Third Name 7 Group Name3 Hello
3 Third Name 8 Group Name4 Hello World

不知道在这里使用Linq是否更好。 只是想把它扔在那里。

编辑:

我做了一些性能测试,发现是使用

var query = fullTable
            .AsEnumerable()
            .Select(x => new
                    {
                        PartnerID = x.Field<string>("PartnerID"),
                        PartnerName = x.Field<string>("Partner Name")
                    })
            .Distinct();

如果不需要在dataview方法上创建的其他DataTable对象,则比DataView解决方案快很多。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM