如何使用匿名LINQ结果填充DataTable

我有以下LINQ查询:

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 }; 

如何将这些结果放入DataTable中,然后我可以绑定到DataGridView控件?

这就是我目前正在做的事情:

  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); } } 

更新:这是我更新的代码:

 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 list = new List(); 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("date", item.date); row.SetField("taskName", item.taskName); row.SetField("projectName", item.projectName); row.SetField("projectDesc", item.projectDesc); row.SetField("departmentName", item.departmentName); row.SetField("taskEstimatedHours", item.taskEstimatedHours); row.SetField("timesheetHours", item.timesheetHours); list.Add(row); } table = list.CopyToDataTable(); } 

这是我在SSMS中测试的SQL查询(应该等同于LINQ查询):

 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 

如果你真的想填充DataTable:

 // your query var timesheets = ... // design table first DataTable table = new DataTable(); table.Columns.Add(new DataColumn { ColumnName = "TaskName", DataType = typeof(String); }); ... List list = new List(); foreach (var t in timesheets) { var row = table.NewRow(); row.SetField("TaskName", t.taskName); // extension method from System.Data.DataSetExtensions.dll ... list.Add(row); } DataTable table = list.CopyToDataTable(); // extension method too 

或更多LINQ方式:

 timesheets .Select(t => { var row = table.NewRow(); ... return row; }) .CopyToDataTable(); 

或者使用相同的查询语法。 实施方法:

 static DataRow NewRow(DataRow row, string taskName, ....) { ... } 

然后查询自己:

 (from ... where ... select NewRow(table.NewRow(), task.Name, ...) ).CopyToDataTable(); 

调用.ToList()
生成的List也可以绑定到DataGridView,并且比DataTable更容易使用。

我正在使用FastMember来达到这个目的。 它使用IL而不是reflection (更快)来自动迭代所有属性和字段值。 来自网站的代码示例:

 IEnumerable data = ... var table = new DataTable(); using(var reader = ObjectReader.Create(data)) { table.Load(reader); }