C# DataTable Linq select distinct values where column equals 'x' - c#

I have a Datatable (Groups) designed like so
ColumnA|ColumnB
X|Apple
Y|Purple
X|Apple
X|Mango
I basically want to select from columna where it's X and get the disinct from ColumnB
This is what I have
var names = (from DataRow dr in Groups.Rows
orderby (string)dr["ColumnB"]
select (string)dr["ColumnB"]).Distinct();
This will give me distinct but it gives me Purple, and i dont want purple.
Thanks!

var names = (from DataRow dr in Groups.Rows
where dr["ColumnA"] == "X"
orderby (string)dr["ColumnB"]
select (string)dr["ColumnB"]).Distinct();

DataTable dt2 = dt1.Select("ColumnA = 'X'").CopyToDataTable().DefaultView.ToTable(true, "ColumnB");
So here we are selecting only the rows of data that you want, only rows where columnA is X. Then we choose only to see columnB, but with unique values only. Doing it in this order, you'll receive another datatable to play with. It'll only contain 1 column, columnB, and it'll only have unique/distinct values.
Enjoy.

If your return has more than one value and you want to Distinct the whole set by just one of the values you should use a custom IEqualityComparer.
var names = (from DataRow dr in Groups.Rows
where (string)dr["ColumnA"] == "X"
orderby (string)dr["ColumnB"]
select new {
ColumnA = (string)dr["ColumnA"],
ColumnB = (string)dr["ColumnB"]
}).Distinct(new MyCustomEqualityComparer());
edit: to include where clause
edit2: changed to custom IEqualityComparer

Related

Multiple string values to compare with one. something like attributetocheck.Equals(att1,att2,att3)

I have multiple attributes say att1,att2,att3 which can be separated by any of the separator.
I want to have an "OR" condition in the below query to check if the row value in COLUMN1 is equal or not.
Since .Equals can only have a string ,Can any one suggest any other way of doing it.
string result = string.Join(",", attributes);
List<string> query = (from DataRow dr in response.Output.Tables[0].Rows
where dr["COLUMN1"].ToString().Equals(result)
select dr["COLUMN2"].ToString()).ToList<string>();
Instead of joining attributes to an string, use it's Contains method
List<string> query = (from DataRow dr in response.Output.Tables[0].Rows
where attributes.Contains(dr["COLUMN1"].ToString())
select dr["COLUMN2"].ToString()).ToList<string>()

Datatable LINQ select datarow only returning one row and how to order

I have a datatable with 4 columns
- A|1|Apple|Turnip
- A|2|Water|Fruit
- B|1|Water|Orange
- B|2|Water|Mango
- C|1|Hello|World
What I want to do is select distinct column A. Then I want to select distinct columns 2,3,4 based on column A.
This is what i'm using to select distinct column A. My question with this first part is how do you order by column A (linkControl). Member is my datatable, and this returns every distrinct column a
var linkControl = Member.AsEnumerable()
.Select(row => new
{
linkCon = row.Field<string>("LinkControl")
})
.Distinct();
Then because I want to iterate each of the linkCons I do the following, which only returns one datarow even though there is about 20 datarows for each linkCon. How do i return all the rows?
foreach (var linkC in linkControl)
{
var linkControllink = (from DataRow dr in ADMemberships.Rows
where dr["LinkControl"] == linkC.linkCon
orderby (string)dr["URLDescription"]
select dr);
}
foreach (var lcl in linkControllink)
{
//only has one row in it
}
I had to change the code to where dr["LinkControl"].ToString() == linkC.linkCon.ToString() and i dont really understand why.

c# all distincts value from datatable

I've found this piece of code that can be used to get all distinct values. But my datatable has 10 columns. The distinctValues only shows the columns I write in the toTable(); Is it possible to use this function, but also show the rest of the columns?
DataView view = new DataView(table);
DataTable distinctValues = view.ToTable(true, "Column1", "Column2");
Unless those columns you mention are the full key to the table, there is no guarantee that for a particular combination of those two columns the other columns will have exactly one value.
And if they were the key, then there would be no need to use a "distinct" filter.
You can use Linq-To-DataTable
var distinct = from row in table.AsEnumerable()
group row by new
{
Col1 = row.Field<string>("Column1"),
Col2 = row.Field<string>("Column2")
} into Group
select Group.First()
DataTable tblDistinct = distinctRows.CopyToDataTable();
(assuming that you just want an arbitrary row[the first])

vb.net LINQ select Distinct to a List

I have a datatable with a column that has some duplicate values, I want to add those values to a listbox but without duplicates
I tried the following
Dim a = From row In table.AsEnumerable.Distinct.ToList Select row.Field(Of String)("name")
but it gives me duplicate values, How can it be done without duplicates?
I believe there are some more column(s) which are unique in each row that's why the distinct doesn't return the result as expected. Instead you should need to select the columns first than apply the distinct to it.
So try this instead :
Dim a = (From row In table.AsEnumerable()
Select row.Field(Of String)("name")).Distinct().ToList()
Hope this will help !!
You can pass an IEqualityComparer to the distinct function. See this answer Distinct() with lambda?
I had the same problem. I found that on anonymous type distinct works. So I first do the distinct and then copy into a list.
Dim _ret = New List(Of Marcas)()
For Each m In lista.Select(Function(s) New With {Key .id = s.BrandNo, .nombre = s.BrandName}).Distinct()
_ret.Add(New Marcas With {.id = m.id, .nombre = m.nombre})
Next

How to select a field with linq on datarow

I have this linq query :
string title = from DataRow r in (OleDB.DataItems.Tables[0]).Rows
select r.Title;
and I'd like to extract the field Title (from Database) on the row (rows will be 1, not more, so that's I put on a string and not in a string[].
How can I do it?
VStudio says that DataRow doesnt contain the definition of Title, but the field Title exist on the database.
I making confusion :)
As Frédéric Hamidi said, you don't need LINQ.
However, if you still want to do it that way (overkill) and you know that there is always a single table with a single row, do:
DataSet data = new DataSet();
var table = (from a in data.Tables.Cast<DataTable>() select a).Single();
var row = (from a in table.Rows.Cast<DataRow>() select a).Single();
String title = row.Field<String>("Title");
or
DataSet data = new DataSet();
var table = (from a in data.Tables.Cast<DataTable>() select a).SingleOrDefault();
var row = (from a in table.Rows.Cast<DataRow>() select a).SingleOrDefault();
String title = row.Field<String>("Title");
I used a DataSet because I don't know how your object is structured.
You don't need LINQ since you only want to fetch the Title field of the first row in the collection:
string title = OleDB.DataItems.Tables[0].Rows[0]["Title"];
try
string title = (from DataRow r in (OleDB.DataItems.Tables[0]).Rows
select r.Title).First();
Linq returns an enumerable collection as it doesn't know there will be only one item. Calling the First method will return the first item from the query.
Edit: Hang on, I have blatantly missed the problem you originally mentioned (but you'll still need the above)!
A data row contains fields, not properties as such. What you'll need to do is
select r.Field<string>("Title")
So your entire query will be
string title = (from DataRow r in (OleDB.DataItems.Tables[0]).Rows
select r.Field<string>("Title")).First();
It's better to use FirstOrDefault, in case there are no rows:
string title = (from DataRow r in (OleDB.DataItems.Tables[0]).Rows
select r.Title).FirstOrDefault();
Usually, if you need to perform such an action, you would cast the DataRow object to your strongly typed object corresponding with the table in your database.
I assume there is a class "Book" which contains the field "Title":
Book selectedBook = (Book) from DataRow r in (OleDB.DataItems.Tables[0]).Rows[0]
string sTitle = selectedBook.Title;
Hope this helps.

Categories

Resources