Reputation: 6699
I have a data table and I want to select all distinct names from the result. I wrote following linq query for it.
var distinctRows = (from DataRow myDataRow in myDataTable.Rows
select new { col1 = myDataRow ["Name"]}).Distinct();
Now how can I iterate through distinctRows? Seems like I cannot do foreach(DataRow Row in distinctRows)
, It gives me "Cannot convert type 'AnonymousType#1' to 'System.Data.DataRow'" error
Upvotes: 0
Views: 539
Reputation: 7140
You can also foreach them but first you had to List them as the following :
List<string> rslt =(from DataRow myDataRow in myDataTable.Rows
select new { col1 = myDataRow ["Name"].ToString()}).Distinct().ToList();
foreach(string str in rlst)
{}
Hope this helped
Upvotes: 0
Reputation: 5404
The problem here is that you're selecting a new anonymous type by doing select new { col1 = myDataRow ["Name"]}
and not the actual row itself. So when you try to iterate this as DataRow, it will error out because your anonymous type being selected is not of type DataRow.
If you want to be able to select a whole data row and not just the name field, you will need to implement a custom IEqualityComparer for data row to pass to the Distinct() extension method.
An example would be:
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();
}
}
Then using it:
var distinctRows = (from DataRow myDataRow in myDataTable.Rows
select myDataRow).Distinct(new NameComparer());
Upvotes: 0
Reputation: 23157
To build on SLaks answer . . .
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
}
Upvotes: 0
Reputation: 22849
That's because the return value isn't a DataRow. It's an ad-hoc type that containes the property col1.
Upvotes: 0
Reputation: 125488
You can use the keyword var
to refer to anonymous types (which is what you're returning an IEnumerable<>
of).
foreach(var row in distinctRows)
{
// do something with each anonymous type instance
}
Since you're only returning anonymous types with one string property however, you may as well project an IEnumerable<string>
Upvotes: 1
Reputation: 241641
Since you're only selecting one field, you don't need an anonymous type here. Just select the names and then iterate over the distinct ones. To wit:
var distinctNames = (from DataRow myDataRow in myDataTable.Rows
select myDataRow.Field<string>("Name")
).Distinct();
foreach(var name in distinctNames) {
Console.WriteLine(name);
}
Note that the error makes it very clear what the problem is here. You are trying to convert an instance of an anonymous type to an instance of DataRow
and that is impossible. Without changing your code, you could iterate this as
foreach(var item in distinctRows) {
Console.WriteLine((string)item.col1);
}
But I would change this as per the above as you don't need the anonymous type and your variable names and field names are poor.
Upvotes: 3
Reputation: 23472
That's because myDataRow["Name"]
doesn't return a DataRow
. Try
foreach(var item in distinctRows) {}
Upvotes: 0
Reputation: 887453
Those aren't DataRows; they're anonymous objects.
To loop through them, you need to declare the variable using the var
keyword.
However, there's no point in the anonymous type in the first place.
You can change your query to select myDataRow.Field<string>("Name")
to get a set of strings.
Upvotes: 2