2011-01-10 54 views
0

我有一个数据表,我想从结果中选择所有不同的名称。我为它写了下面的linq查询。c#linq问题

var distinctRows = (from DataRow myDataRow in myDataTable.Rows 
        select new { col1 = myDataRow ["Name"]}).Distinct(); 

现在我该如何迭代distinctRows?似乎我不能做foreach(DataRow Row in distinctRows),它给我“不能转换类型'匿名类型#1'到'System.Data.DataRow'”错误

+4

你读过错误吗? – SLaks 2011-01-10 20:17:18

+4

未来,如果问题的标题描述了您的问题,您可能会得到更好的结果。 “C#linq问题”没有告诉我们什么; C#和linq已经是标签了,我们知道它是一个问题。 – 2011-01-10 20:21:43

+0

@Eric,谢谢你指出。对不起,使用愚蠢的标题:) – imak 2011-01-10 21:50:19

回答

3

由于您只选择了一个字段,因此您不需要匿名类型。只需选择名称,然后遍历不同的名称即可。即:

var distinctNames = (from DataRow myDataRow in myDataTable.Rows 
        select myDataRow.Field<string>("Name") 
        ).Distinct(); 

foreach(var name in distinctNames) { 
    Console.WriteLine(name); 
} 

请注意,错误很清楚地表明问题出在哪里。您正尝试将匿名类型的实例转换为DataRow的实例,这是不可能的。不改变你的代码,你可以遍历这个作为

foreach(var item in distinctRows) { 
    Console.WriteLine((string)item.col1); 
} 

但我想改变这种按照上面的,你不需要匿名类型和变量名和字段名都很差。

2

那些不是DataRows;他们是匿名对象。
要遍历它们,您需要使用var关键字声明变量。

然而,首先匿名类型没有意义。
您可以将您的查询更改为select myDataRow.Field<string>("Name")以获取一组字符串。

0

这是因为myDataRow["Name"]没有返回DataRow。尝试

foreach(var item in distinctRows) {} 
1

您可以使用关键字var来引用匿名类型(这是您返回的IEnumerable<>)。

foreach(var row in distinctRows) 
{ 
    // do something with each anonymous type instance 
} 

既然你只返回匿名类型的一个字符串属性不过,你不妨投影IEnumerable<string>

0

这是因为返回值不是一个DataRow。这是一个包含属性col1的ad-hoc类型。

0

建立在SLaks的答案。 。 。

var distinctRows = (from DataRow myDataRow in myDataTable.Rows 
        select new { col1 = myDataRow ["Name"]}).Distinct(); 

foreach(var row in distinctRows) 
{ 
    System.Console.Writeline(row.col1); //should work fine 
} 
0

这里的问题是,您选择一个新的匿名类型,通过做select new { col1 = myDataRow ["Name"]}而不是实际的行本身。因此,当您尝试将此迭代为DataRow时,它将会出错,因为您选择的匿名类型不是DataRow类型。

如果您希望能够选择整个数据行而不仅仅是名称字段,则需要为数据行实现自定义IEqualityComparer以传递给Distinct()扩展方法。

一个例子是:

public class NameComparer : IEqualityComparer<DataRow> 
{ 
    public bool Equals(DataRow left, DataRow right) 
    { 
     return left.Field<string>("Name").Equals(right.Field<string>("Name")); 
    } 

    public int GetHashCode(DataRow obj) 
    { 
     return obj.ToString().GetHashCode(); 
    } 
} 

然后使用它:

var distinctRows = (from DataRow myDataRow in myDataTable.Rows 
        select myDataRow).Distinct(new NameComparer()); 
0

你也可以的foreach他们,但首先你必须列出来,如下所示:

List<string> rslt =(from DataRow myDataRow in myDataTable.Rows 
        select new { col1 = myDataRow ["Name"].ToString()}).Distinct().ToList(); 

foreach(string str in rlst) 
{} 

希望这有帮助