GROUP BY in datatable select using c# - c#

I have a dataTable which has rows as shown in below image,
I would like to write groupby statement with select on that datatable for getting output as below,

select ApplicationName, count(*) from DataTableName
group by ApplicationName
where DataTableName should be replaced by the actual name of your table in the database, and ApplicationName should be replaced by the name of the column in that table that contains applicatin name

Try this using LINQ in C#
var result = from tab in dt.AsEnumerable()
group tab by tab["ApplicationNmae"]
into groupDt
select new
{
ApplicationNmae = groupDt.Key,
Sum = groupDt.Sum((r) => decimal.Parse(r["Count"].ToString()))
};
DataTable dt1 = new DataTable();
dt1 = dt.Clone();
foreach (var item in result)
{
DataRow newRow = dt1.NewRow();
newRow["ApplicationNmae"] = item.ApplicationNmae;
newRow["Count"] = item.Sum;
dt1.Rows.Add(newRow);
}
Grid.DataSource = dt1;
Ref: Group by in DataTable Column sum

Simply this...
SELECT ApplicationName, COUNT(*) [Count]
FROM THETABLENAME
GROUP BY ApplicationName
or with ordering and filtering (where there is a duplication and order by the count)...
SELECT ApplicationName, COUNT(*) [Count]
FROM THETABLENAME
GROUP BY ApplicationName
HAVING COUNT(*) > 1
ORDER BY COUNT(*) DESC

Related

How to Get Single Column Value in c# LINQ?

DataTable Master_Table = Execute_Manager.getTableDataSet(connection, select_query, master_table);
string RuleName = (From EachRow in Master_Table
where EachRow.Field<string>("RuleID") == "123456"
Select EachRow.Field<string>("RuleName")).CopyToDataTable().ToString();
I need to get single Column Value using LINQ in Datatable c#
You could do something like the following I have added in the two examples below:
string carManufacturer = "BMW";
DataTable dt = new DataTable();
int id = (from DataRow dr in dt.Rows
where (string)dr["CarManufacturer"] == carManufacturer
select (int)dr["id"]).FirstOrDefault();
string columnValue = dt.Rows[0]["ColumnName"].ToString();
What column value are you trying to fetch from your data table?

Check if column exists before execute select clause

I use a DataTable in a foreach loop from sql like:
foreach(var i in tasks)
{
// query sql
var timeOfTasks = db.GetTableBySQL($"exec usp_Get_WorkedProyectTime #TaskTypeCategoryId = '{i.TaskTypeCategoryId}', #TaskId= '{i.TaskId}'");
// read columns (different rows have different columns)
var progressToBackCheck = (from DataRow dr in timeOfTasks.Rows select dr["ProgressToBackCheck"]).FirstOrDefault();
var backcheckToCorrection = (from DataRow dr in timeOfTasks.Rows select dr["BackcheckToCorrection"]).FirstOrDefault();
var correctionsToCompleted = (from DataRow dr in timeOfTasks.Rows select dr["CorrectionsToCompleted"]).FirstOrDefault();
var progressToCompleted = (from DataRow dr in timeOfTasks.Rows select dr["ProgressToCompleted"]).FirstOrDefault();
}
Not all task results have the same data rows. And each row doesn't contain all fields. Is there a way to check if a column exists in the result, before I use query for it?
You can try to use DataColumnCollection.Contains to check the column is exists in the data table.
if (timeOfTasks.Columns.Contains("ProgressToBackCheck"))
{
}
You can use this linq to get field, add where linq
where timeOfTasks.Columns.Contains("ProgressToBackCheck")
look like this.
var progressToBackCheck = (
from DataRow dr in timeOfTasks.Rows
where timeOfTasks.Columns.Contains("ProgressToBackCheck")
select dr["ProgressToBackCheck"]
).FirstOrDefault();

Delete using LINQ by joining two datatables

I have two datatable DurationByCurrency(inside a dataset) and Fund which looks like below
I want to delete the rows in Duration By Currency Datatable whose FundCode has value as 2 in Fund Dt by performing a join.
var result = from table1 in raptorDS.Tables[RaptorTable.DurationByCurrency].AsEnumerable()
join table2 in fundDT.AsEnumerable()
on table1.Field<string>("FundCode") equals table2.Field<string>("FundCode") into ps
from row in ps.DefaultIfEmpty()
{
//delete query
}
Please help me on this as I am new to LINQ.
var result = from row1 in raptorDS.Tables[RaptorTable.DurationByCurrency].AsEnumerable()
join row2 in fundDT.AsEnumerable()
on row1.Field<string>("FundCode") equals row2.Field<string>("FundCode")
where row1.Field<string>("value")
equals "2" select row1;
result.ToList().ForEach(row => row.Delete());
sample test code for linqpad:
void Main()
{
//sample data for test
DataSet ds = new DataSet();
ds.Tables.Add(GetTable1());
ds.Tables.Add(GetTable2());
var result = ( from rec1 in ds.Tables[0].AsEnumerable()
join rec2 in ds.Tables[1].AsEnumerable()
on rec1.Field<string>("FC") equals rec2.Field<string>("FC")
where rec2.Field<int>("Value") == 2 select rec1);
result.ToList().ForEach(row => row.Delete());
//now you have only "ABCD" and "AZY" in table 1
//ds.Tables[0].Dump(); linqpad display result
}
DataTable GetTable1()
{
DataTable table = new DataTable();
table.Columns.Add("FC", typeof(string));
table.Rows.Add("ABCD");
table.Rows.Add("XYZ");
table.Rows.Add("AZY");
return table;
}
DataTable GetTable2()
{
DataTable table = new DataTable();
table.Columns.Add("FC", typeof(string));
table.Columns.Add("Value", typeof(int));
table.Rows.Add("ABCD", 1);
table.Rows.Add("XYZ", 2);
table.Rows.Add("AZY",3);
return table;
}

How to populate DataTable with anonymous LINQ result

I have the following LINQ query:
var timesheets = from timesheet in entities.Timesheets
join timesheetTask in entities.Timesheet_Task on timesheet.Id equals timesheetTask.Timesheet_Id
join task in entities.Tasks on timesheetTask.Task_Id equals task.Id
join project in entities.Projects on task.Project_Id equals project.Id
join department in entities.Departments on project.Department_Id equals department.Id
where timesheet.Employee_Id == employeeId
select new
{
date = timesheet.Date,
taskName = task.Name,
projectName = project.Name,
projectDesc = project.Description,
departmentName = department.Name,
taskEstimatedHours = task.Estimated_Hours,
timesheetHours = timesheetTask.Hours
};
How can I put these results into a DataTable which I can then bind to a DataGridView control?
This is what I'm currently doing:
table.Columns.Add("date");
table.Columns.Add("taskName");
table.Columns.Add("projectName");
table.Columns.Add("projectDesc");
table.Columns.Add("departmentName");
table.Columns.Add("taskEstimatedHours");
table.Columns.Add("timesheetHours");
foreach (var item in timesheets)
{
table.Rows.Add(item.date, item.taskName, item.projectName,
item.projectDesc, item.departmentName, item.taskEstimatedHours,
item.timesheetHours);
}
}
Update: Here is my updated code:
DataTable table = new DataTable();
using (PTMS_DataEntities entities = new PTMS_DataEntities())
{
var timesheets = from timesheet in entities.Timesheets
join timesheetTask in entities.Timesheet_Task on timesheet.Id equals timesheetTask.Timesheet_Id
join task in entities.Tasks on timesheetTask.Task_Id equals task.Id
join project in entities.Projects on task.Project_Id equals project.Id
join department in entities.Departments on project.Department_Id equals department.Id
where timesheet.Employee_Id == employeeId
select new
{
date = timesheet.Date,
taskName = task.Name,
projectName = project.Name,
projectDesc = project.Description,
departmentName = department.Name,
taskEstimatedHours = task.Estimated_Hours,
timesheetHours = timesheetTask.Hours
};
table.Columns.Add("date", typeof(DateTime));
table.Columns.Add("taskName", typeof(string));
table.Columns.Add("projectName", typeof(string));
table.Columns.Add("projectDesc", typeof(string));
table.Columns.Add("departmentName", typeof(string));
table.Columns.Add("taskEstimatedHours", typeof(int));
table.Columns.Add("timesheetHours", typeof(int));
List<DataRow> list = new List<DataRow>();
foreach (var item in timesheets)
{
//table.Rows.Add(item.date, item.taskName, item.projectName,
// item.projectDesc, item.departmentName, item.taskEstimatedHours,
// item.timesheetHours);
var row = table.NewRow();
row.SetField<DateTime>("date", item.date);
row.SetField<string>("taskName", item.taskName);
row.SetField<string>("projectName", item.projectName);
row.SetField<string>("projectDesc", item.projectDesc);
row.SetField<string>("departmentName", item.departmentName);
row.SetField<int>("taskEstimatedHours", item.taskEstimatedHours);
row.SetField<int>("timesheetHours", item.timesheetHours);
list.Add(row);
}
table = list.CopyToDataTable();
}
Here is the SQL query I tested in SSMS (which should be the equivalent of the LINQ query):
SELECT dbo.Department.Name, dbo.Task.Name AS Expr1, dbo.Task.Estimated_Hours, dbo.Timesheet.Date, dbo.Project.Name AS Expr2, dbo.Project.Description,
dbo.Timesheet_Task.Date AS Expr3
FROM dbo.Department INNER JOIN
dbo.Project ON dbo.Department.Id = dbo.Project.Department_Id INNER JOIN
dbo.Task ON dbo.Project.Id = dbo.Task.Project_Id INNER JOIN
dbo.Timesheet_Task ON dbo.Task.Id = dbo.Timesheet_Task.Task_Id INNER JOIN
dbo.Timesheet ON dbo.Timesheet_Task.Timesheet_Id = dbo.Timesheet.Id
If you really want to populate DataTable:
// your query
var timesheets = ...
// design table first
DataTable table = new DataTable();
table.Columns.Add(new DataColumn
{
ColumnName = "TaskName",
DataType = typeof(String);
});
...
List<DataRow> list = new List<DataRow>();
foreach (var t in timesheets)
{
var row = table.NewRow();
row.SetField<string>("TaskName", t.taskName); // extension method from System.Data.DataSetExtensions.dll
...
list.Add(row);
}
DataTable table = list.CopyToDataTable(); // extension method too
Or more LINQ way:
timesheets
.Select(t =>
{
var row = table.NewRow();
...
return row;
})
.CopyToDataTable();
Or in same query syntax. Implement a method:
static DataRow NewRow(DataRow row, string taskName, ....)
{
...
}
Then query itself:
(from ...
where ...
select NewRow(table.NewRow(), task.Name, ...)
).CopyToDataTable();
Call .ToList().
The resulting List<T> can also be bound to a DataGridView, and is easier to work with than a DataTable.
I'm using FastMember for this purpose. It uses IL instead of reflection (much faster) to iterate over all of the property and field values automatically. Code sample from the site:
IEnumerable<SomeType> data = ...
var table = new DataTable();
using(var reader = ObjectReader.Create(data))
{
table.Load(reader);
}

merge 2 datatable

I have 2 Datatable dt and dt2
var dt = MultiCheckCombo3.GetAllChechedBox();
var dt2 =manager.GetAllStudents(student_id, classid);
In the first table dt are two columns "id_staff" and "name_staff"
In the second table are several columns but 2 of them repeat "id_staff" and "name_staff"
I want to create a new DataTable with the fields "id_staff" and "name_staff" common DataTable dt and dt2
how joined these tables?
dt3= dt+dt2
You can use Linq to join the two tables. See the following example.
Code from the article:
var innerGroupJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
select new { CategoryName = category.Name, Products = prodGroup };
Have a look at the DataTable.Merge method:
This link from Microsoft has an example of how to do this
If dt and dt2 are DataTables, you can use datatable merge.
DataTable dt3 = dt.Copy()
dt3.Merge(dt2, false, MissingSchemaAction.Ignore)
Maybe something like this:
var dt=new DataTable();
dt.Columns.Add("id_staff",typeof(int));
dt.Columns.Add("name_staff",typeof(string));
var dt2=new DataTable();
dt2.Columns.Add("id_staff",typeof(int));
dt2.Columns.Add("name_staff",typeof(string));
dt.Rows.Add(1,"test");
dt2.Rows.Add(2,"test2");
var result=
(
from datatable1 in dt.AsEnumerable()
select new
{
id_staff=datatable1.Field<int>("id_staff"),
name_staff=datatable1.Field<string>("name_staff")
}
).Concat
(
from datatable2 in dt2.AsEnumerable()
select new
{
id_staff=datatable2.Field<int>("id_staff"),
name_staff=datatable2.Field<string>("name_staff")
}
);

Categories

Resources