LINQ TO DataSet: Multiple group by on a data table - c#

I am using Linq to dataset to query a datatable. If i want to perform a group by on "Column1" on data table, I use following query
var groupQuery = from table in MyTable.AsEnumerable()
group table by table["Column1"] into groupedTable
select new
{
x = groupedTable.Key,
y = groupedTable.Count()
}
Now I want to perform group by on two columns "Coulmn1" and "Column2". Can anybody tell me the syntax or provide me a link explaining multiple group by on a data table??
Thanks

You should create an anonymous type to do a group by multiple columns:
var groupQuery = from table in MyTable.AsEnumerable()
group table by new { column1 = table["Column1"], column2 = table["Column2"] }
into groupedTable
select new
{
x = groupedTable.Key, // Each Key contains column1 and column2
y = groupedTable.Count()
}

Related

Duplicates In DataTable, Getting Last By Specifying Two Properties

I have a DataTable, with two columns of type String named ID and Value. These values are not required to be unique.
As I add to my DataTable throughout my application, at some point I am trying to get the last item that was added that meets the value of the two properties. For example, for all records where ID = 1 and Value = 2, there may be several. I need the last record.
I have been trying to use LINQ groupbys, the MyDataTable variable is my datatable.:
var groupQuery = from table in MyDataTable.AsEnumerable()
group table by new {column1 = table["PERSON_GU"], column2 = table["FIELD"]}
into groupedTable
select new
{
x = groupedTable.Key, // Each Key contains column1 and column2
y = groupedTable.Count()
};
I cant figure out how to make this select last though, it appears to return an anonymous type which is a little out of my development skill wheelhouse.
In summary, I have a datatable with two columns, I am trying to group my final datatable by these column values, and then get the last item.
If you want the last DataRow of each group:
var groupQuery =
from table in MyDataTable.AsEnumerable()
group table by new {column1 = table["PERSON_GU"], column2 = table["FIELD"]}
into groupedTable
select groupedTable.Last();

How to select columns and sum of columns using group by keyword from data table in c#

i am having a DataTable called dtTest. i just need to select columns from the C# Datatable using Linq concepts
Data Table Name is DtTest.
Example : DtTest Contains the following data's,
i want the result as below, that is i need the SUM of Qty and Amount columns based on group INO...
Can anyone Please help me to solve this....
DtTest
.AsEnumerable()
.GroupBy
(
x=>
new
{
BNO = x.Field<int>("BNO"),
INO = x.Field<int>("INO"),
Desp = x.Field<string>("Desp"),
Rate= x.Field<decimal>("Rate")
}
)
.Select
(
x=>
new
{
x.Key.BNO,
x.Key.INO,
x.Key.Desp,
Qty = x.Sum(z=>z.Field<int>("Qty")),
x.Key.Rate,
Amount = x.Sum(z=>z.Field<decimal>("Amount"))
}
);

Set values with conditions LINQ

I'm selecting some data from table A with a column value and type which have relationship with table B where there is a column coef that contains (-1,0,1)
When retrieving from A I want to multiply the value with coef.
Something like this?
var result = from a in tableA
join b in tableB on a.Key = b.ForeignKey
select new
{
Value = a.value * b.coef
};
You could use a LINQ expression to do it in one line:
dt.Rows.ForEach(x => x["value"] = (double)x["value"] * (double)x["coef"]);
or you could just add another column to the DataTable:
dt.Columns.Add("Result", typeof(decimal));
dt["result"] = "value * coef";

Group by one column and Distinct by another column using Linq

I am using a Linq query to groupBy a column name and return a list of rows.
var query = from row in ProcessSummaryData.AsEnumerable()
group row by new { Key = row .Field<string>("GroupDescription") } into g
select new
{
GroupDescription = g.Key,
Values = g.ToList(),
};
The output of this query is something like this
GroupDescription Values
1 12,abc,xyz
12,abx,yut
13,tye,lki
2 14,asd,acd
Now the in the above example Values is a DataRow and I have just given an example of values in it.
Now what I want is that for GroupDescription '1' the output only has one row with '12' value.
I have tried a few things one of which is to have another Linq query on first list but that's over complicating things.
How do I use linq to group by first column and then use Distinct on certain column returned list to get only Distinct rows?
To get the first occurrence of a field's values you can group by that field and then take the first row of each grouping.
var query = from row in ProcessSummaryData.AsEnumerable()
group row by new { Key = row .Field<string>("GroupDescription") } into g
select new
{
GroupDescription = g.Key,
Values = (from value in g.ToList()
group value by value["Id"] into valueGroup
select valueGroup.First()).ToList()
};

Merging 2 datatables in to 1 datatable with same number of rows.

How can i merge two Datatables into the same row. I am using different stored procedures to get data into datasets. In asp.net using c#, i want to merge them so there are same number of rows as table 1 with an added column from table 2.
For example:
DataTable table1 = dsnew.Tables[0];
DataTable table2 = dsSpotsLeft.Tables[0];
table1.Merge(table2);
This is fetching me 4 rows instead of 2 rows. What am i missing here? Thanks in advance!!
You cannot use the method Merge in this case, instead you should create new DataTable dt3, and then add columns and rows based on the table 1 and 2:
var dt3 = new DataTable();
var columns = dt1.Columns.Cast<DataColumn>()
.Concat(dt2.Columns.Cast<DataColumn>());
foreach (var column in columns)
{
dt3.Columns.Add(column.ColumnName, column.DataType);
}
//TODO Check if dt2 has more rows than dt1...
for (int i = 0; i < dt1.Rows.Count; i++)
{
var row = dt3.NewRow();
row.ItemArray = dt1.Rows[i].ItemArray
.Concat(dt2.Rows[i].ItemArray).ToArray();
dt3.Rows.Add(row);
}
Without knowing more about the design of these tables, some of this is speculation.
What it sounds like you want to perform is a JOIN. For example, if you have one table that looks like:
StateId, StateName
and another table that looks like
EmployeeId, EmployeeName, StateId
and you want to end up with a result set that looks like
EmployeeId, EmployeeName, StateId, StateName
You would perform the following query:
SELECT Employee.EmployeeId, Employee.EmployeeName, Employee.StateId, State.StateName
FROM Employee
INNER JOIN State ON Employee.StateId = State.StateId
This gives you a resultset but doesn't update any data. Again, speculating on your dataset, I'm assuming that your version of the Employee table might look like the resultset:
EmployeeId, EmployeeName, StateId, StateName
but with StateName in need of being populated. In this case, you could write the query:
UPDATE Employee
SET Employee.StateName = State.StateName
FROM Employee
INNER JOIN State ON Employee.StateId = State.StateId
Tested in SQL Server.
Assuming you have table Category and Product related by CategoryID, then try this
var joined = from p in prod.AsEnumerable()
join c in categ.AsEnumerable()
on p["categid"] equals c["categid"]
select new
{
ProductName = p["prodname"],
Category = c["name"]
};
var myjoined = joined.ToList();
Sources
LINQ query on a DataTable
Inner join of DataTables in C#
http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataset/thread/ecb6a83d-b9b0-4e64-8107-1ca8757fe58c/
That was a LINQ solution. You can also loop through the first datatable and add columns from the second datatable

Categories

Resources