How to convert this LINQ Query result back to DataTable object? - c#

I have DataTable object (OutputDT1), I want to use LINQ to group by column ConfirmedBy, then convert it back to a DataTable object which has only two columns ConfirmBy and Count.
var result = from row in OutputDT1.AsEnumerable()
group row by new
{
ConfirmedBy = row.Field<string>("ConfirmedBy")
}
into grp
select new
{
ConfirmedBy = grp.Key.ConfirmedBy,
Count = grp.Count(),
};

A simple way would be:
DataTable dt = new DataTable();
foreach(var item in result)
{
dt.Rows.Add(item.ConfirmedBy, item.count);
}

Using the solution from How to: Implement CopyToDataTable<T> Where the Generic Type T Is Not a DataRow
we can write:
var result = (from row in OutputDT1.AsEnumerable()
group row by row.Field<string>("ConfirmedBy") into grp
select new
{
ConfirmedBy = grp.Key,
Count = grp.Count(),
}).CopyToDataTable();

Related

Unable to cast object of type grouping to datarow after i grouped datatable with linq

Hi basically i wanted to group my datatable by the department column, i want to load the results back into another datatable through looping but it keeps giving me an error, im not sure how to group a datatable with linq and load it into another datatable other than looping
here is my code
DataTable data = new DataTable();
data.Columns.Add("Department");
var query1 = dtClone.AsEnumerable().GroupBy(row => row.Field<string>("department"));
if (query1.Any())
foreach(DataRow dr in query1)//here
{
DataRow newrow = data.Rows.Add();
newrow.SetField("Department", dr.Field<string>("department"));
}
foreach (DataRow row in data.Rows)
MessageBox.Show(row[0].ToString());
another linq query i tried
DataTable data = new DataTable();
data.Columns.Add("Department");
var query1 = from r in dtClone.AsEnumerable()
orderby r.Field<string>("department") ascending
group r by r.Field<string>("department") into r
select r;
if (query1.Any())
foreach(DataRow dr in query1)
{
DataRow newrow = data.Rows.Add();
newrow.SetField("Department", dr.Field<string>("department"));
}
No need to group data in case of getting distinct records (only one column).
var query1 = dtClone.AsEnumerable().Select(row => row.Field<string>("department")).Distinct();
ORDER BY
var query1 = dtClone.AsEnumerable().Select(row => row.Field<string>("department")).Distinct().OrderBy(s => s);

Join 2 arrays using LINQ with condition

I have two arrays converted from datatables.
I need to join the two arrays on a condition and then databind the final results to a ListView.
The first array has only one column, and the second has several. I need to join them where column txtItemA on searchResults is equal to txtItemNumber on queryResults column.
I'm not sure even if I'm on the right track. Visual Studio is showing a redline under searchresults in this line....
var showResults = from a in searchResults
My code...
ArrayList searchResults = new ArrayList();
foreach (DataRow dataRow in dt2.Rows)
searchResults.Add(string.Join(";", dataRow.ItemArray.Select(item => item.ToString())));
ArrayList queryResults = new ArrayList();
foreach (DataRow dataRow in dt2.Rows)
queryResults.Add(string.Join(";", dataRow.ItemArray.Select(item => item.ToString())));
var showResults = from a in searchResults
join b in queryResults on b.txtItemNumber equals a.txtItemA
select new
{
newseries = searchResults.newseries,
series = searchResults.series
};
ListView1.DataSource = showResults.ToArray();
ListView1.DataBind();
I tried using this code from Gilad Green...
List<string> searchResults = new List<string>();
foreach (DataRow dataRow in dt2.Rows)
searchResults.Add(string.Join(";", dataRow.ItemArray.Select(item => item.ToString())));
List<string> queryResults = new List<string>();
foreach (DataRow dataRow in dt2.Rows)
queryResults.Add(string.Join(";", dataRow.ItemArray.Select(item => item.ToString())));
var showResults = searchResults.Where(item => queryResults.Contains(item.txtItemA)
.Select(item => new {
newseries = item.newseries,
series = item.series
}));
I still cant get this to work..
Errors on item in the line.....Select(item => new {
parameter or local variable cannot have the same name as a method type parameter
and txtItemA
string does contain a definition for txtItemA and no extension method....
Try the following, It uses standard DataRows and I'm guessing the field names based on your sample code.
DataTable dt2 = new DataTable();
var showResults = dt2.Rows.Cast<DataRow>().Join(dt2.Rows.Cast<DataRow>(), a => a.Field<string>("txtItemNumber"), b => b.Field<string>("txtItemA"), (a, b) => new
{
newseries = a.Field<string>("newseries"),
series = a.Field<string>("series")
});
ListView1.DataSource = showResults.ToArray();
ListView1.DataBind();

How to convert linq result to DataTable

I have the following DataTable:
DataTable itemsOnSkid = new DataTable();
itemsOnSkid.Columns.Add("ItemNumber");
itemsOnSkid.Columns.Add("Qty");
And I need to aggregate this datatable by itemnumber. I'm using the following linq code:
var result = from row in itemsOnSkid.AsEnumerable()
group row by row.Field<string>("ItemNumber") into grp
select new
{
ItemNumber = grp.Key,
Qty = grp.Sum(r => r.Field<int>("Qty"))
};
Problem is that I need to replace the first datatable with this result, but I'm not able to use .CopyToDataTable() on result.
How can I convert this result back to a datatable?
You can't use CopyToDataTable() in this case, since the thing you're copying from has to be a DataRow. I think you're stuck doing it manually.
DataTable items = new DataTable();
items.Columns.Add("number");
items.Columns.Add("qty");
var result = from r in items.AsEnumerable()
group r by r.Field<string>("number") into grp
select new {
number = grp.Key,
qty = grp.Sum(r => r.Field<int>("qty"))
};
DataTable newItems = new DataTable();
newItems.Columns.Add("number");
newItems.Columns.Add("qty");
foreach (var item in result) {
DataRow newRow = newItems.NewRow();
newRow["number"] = item.number;
newRow["qty"] = item.qty;
newItems.AddRow(newRow);
}
I have tried fast the same as TFischer, but using directly a DataRow. No extra object.
This is my Code:
private static void Main(string[] args)
{
var itemsOnSkid = CreateDataTable();
FillData(itemsOnSkid);
var result = itemsOnSkid.AsEnumerable().GroupBy(row => row.Field<string>("ItemNumber")).Select(
grp =>
{
var newRow = itemsOnSkid.NewRow();
newRow["ItemNumber"] = grp.Key;
newRow["Qty"] = grp.Sum(r => r.Field<int>("Qty"));
return newRow;
}).CopyToDataTable();
}
private static DataTable CreateDataTable()
{
var itemsOnSkid = new DataTable();
itemsOnSkid.Columns.Add("ItemNumber");
itemsOnSkid.Columns.Add("Qty", typeof(int));
return itemsOnSkid;
}
// Fill some Data in the Table
private static void FillData(DataTable itemsOnSkid)
{
for (int i = 1; i <= 10; i++)
{
var newRow = itemsOnSkid.NewRow();
newRow["ItemNumber"] = i % 3;
newRow["Qty"] = i;
itemsOnSkid.Rows.Add(newRow);
}
}
I Hope it helps.
var query = from empl in te.Employees.AsEnumerable() select empl;
List<Employee> dt = query.ToList();
gdempdetails.DataSource = dt;
gdempdetails.DataBind();
Here's a simpler way to do this
// Create the table if you don't already have it
// Otherwise ignore this part
DataTable newItems = new DataTable();
newItems.Columns.Add("number");
newItems.Columns.Add("qty");
// LINQ query
IEnumerable<DataRow> result = from row in itemsOnSkid.AsEnumerable()
group row by row.Field<string>("ItemNumber") into grp
select newItems.LoadDataRow(new object[]
{
ItemNumber = grp.Key,
Qty = grp.Sum(r => r.Field<int>("Qty"))
}, false);
// Copy rows to DataTable
newItems = result.CopyToDataTable<DataRow>();

How to get the summation in group by statement linq query

I have the following LINQ query :
var groupedData = from b in loans.AsEnumerable()
group b by b.Field<int>("loan_code") & b.Field<int>("emp_num")
into f
select f.CopyToDataTable();
I want to select f and in addition to that the summation of Tot field and copy the result in data table .how to do that?
Get required data
var groupedData = from r in loans.AsEnumerable()
group r by new {
LoanCode = r.Field<int>("loan_code"),
EmpNum = r.Field<int>("emp_num")
} into g
select new {
g.Key.LoanCode,
g.Key.EmpNum,
Tot = g.Sum(r => r.Field<int>("Tot")) // assume integer
};
Then use custom CopyToDataTable method (which works for types that don't implement DataRow) to convert them to DataTable. Or you can build DataTable manually:
DataTable dt = new DataTable();
dt.Columns.Add("loan_code", typeof(int));
dt.Columns.Add("emp_num", typeof(int));
dt.Columns.Add("Tot", typeof(int));
foreach(var data in groupedData)
dt.Rows.Add(data.LoanCode, data.EmpNum, data.Tot);

One columned datatable to List<string>

I have a datatable which contains only one column and all items are strings. How can I convert this to a List<string> using LINQ for example?
I Tried:
DataRow[] rows = dtusers.Select();
var qq = from RowCollection in rows
select new { UserCode = LibStatic.ToStr(RowCollection["UserCode"]) };
List<string> users = new List<string>();
users = qq.Cast<string>().ToList();
There is the easyway which always works:
foreach (DataRow dr in dtusers.Rows)
{
users.Add(dr[0].ToString());
}
You can use LINQ query to do that.
List<string> list = dtusers.AsEnumerable()
.Select(r=> r.Field<string>("UserCode"))
.ToList();
You can try this code,
List<string> list = dt.Rows.OfType<DataRow>().Select(dr => (string)dr["ColumnName"]).ToList();

Categories