2015-11-20 42 views
1

我正在尝试构建一个数据集,以便将其导出到电子表格中,并且必须承认我已达到饱和点! 这些都是我的表:如何使用linq构建动态查询

**Matrix** 
Employee id 
Template id 
Expiry date 

**Employee** 
Id 
Employee Name 

**Template** 
Template Id 
Template Name 

我所试图实现的是所有员工(其中员工将组成数据集的行)的列表和所有模板列表(模板列头)然后我需要为每个员工填写每个模板的截止日期。由于他们还没有获得认证,有些员工将不会有每个模板的失效日期。

我想创造一个员工列表,然后将员工集合矩阵的对象,但不一定会工作,不会每个人都会有每个模板类型的矩阵中的条目中。

我已经使用LINQ工作了好几年,但我在这里有点为难,因为这组数据是如何动态的构建。定期添加新模板,因此无需维护查询。它甚至可以通过使用linq,或者我需要看看在SQL中建立一个视图?

任何帮助将不胜感激。以下是我正在尝试做的一个简单例子!

 Temp1  temp2  temp3  temp4 
Emp1 01/01/2014 02/6/2015    04/06/2012 
Emp2    02/6/2015   
Emp3 01/05/2010  

这是我的数据结构:

enter image description here

编辑

嗯,我还是设法得到的东西的工作,我可以输出到的格式图我描述过,但我不知道它是否特别高效 - 如果有更好的方法,我很想知道它是如何的!

public class EmpMatrix 
    { 
     public int TemplateId { get; set; } 
     public string TemplateName { get; set; } 
     public DateTime? ExpiryDate { get; set; } 
    } 

    public class Classemptemp 
    { 
     public emp Employee { get; set; } 
     public List<EmpMatrix> tempateList { get; set; } 
    } 

    public DateTime? GetExpiry(int template, int empl) 
    { 
     return (from a in _entities.matrices 
      where a.empid == empl && a.tempId == template 
      select a.expiryDate).FirstOrDefault(); 
    } 


    public List<Classemptemp> testing() 
    { 
     List<emp> employees = _entities.emps.ToList(); 
     List<template> TemplateList = _entities.templates.ToList(); 
     List<Classemptemp> empList = (from employee in employees 
      let matrix = TemplateList.Select(template => new EmpMatrix 
      { 
       TemplateId = template.templateId, TemplateName = template.Name, ExpiryDate = GetExpiry(template.templateId, employee.Id) 
      }).ToList() 
      select new Classemptemp 
      { 
       Employee = employee, tempateList = matrix 
      }).ToList(); 
     return empList; 
    } 
+0

首先,是的,它似乎是可能的。然而,你已经有了一些含糊的代码。你有DbContext吗?你对视图有约束力吗?有两个阶段来回答这个问题,一个是:我需要什么查询和两个:我如何将数据表示为上面的表格。 – Heberda

+0

我正在使用MVC,我打算将查询结果绑定到数据网格,然后从控制器操作返回文件结果,以直接将数据作为csv传回客户端。我有一个包含每个表的EDMX,并使用_entites访问实体。所以我可以通过说_entities.employee.ToList();来获得员工名单。 –

+0

我明白了。你有导航属性吗?你的POCO课程是什么样的? – Heberda

回答

0

我在想你可以使用Sys tem.Data.DataTable类并执行如下操作:

public class MatrixCell 
{ 
    public string EmployeeName { get; set; } 
    public string ColumnName { get; set; } 
    public DateTime Date { get; set; } 

    public DataTable ProcessRow(DataTable table) 
    { 
     bool found = false; 

     foreach(DataRow row in table.Rows) 
     { 
      if ((string)row["Employeename"] == EmployeeName) 
      { 
       found = true; 
       row[ColumnName] = Date; 
       break; 
      } 
     } 

     if(!found) 
     { 
      DataRow row = table.NewRow(); 
      row["Employeename"] = EmployeeName; 
      row[ColumnName] = Date; 
      table.Rows.Add(row); 
     } 

     return table; 
    } 
} 

每个MatrixTable对象都代表表中的一个单元格。 应用证明:

class Program 
{ 
    static void Main(string[] args) 
    { 
     using (var db = new TestDB()) 
     { 
      //Initialize DataTable 
      DataTable table = new DataTable(); 
      var columnNames = db.Templates.Select(t => t.TemplateName).ToArray(); 

      table.Columns.Add("Employeename", typeof(string)); 

      foreach (var name in columnNames) 
      { 
       DataColumn column = new DataColumn(name, typeof(DateTime)); 
       column.AllowDBNull = true; 
       table.Columns.Add(column); 
      } 

      //Get Matrix objects 
      var result = db.Matrices.Select(m => new MatrixCell 
      { 
       ColumnName = m.Template.TemplateName, 
       Date = (DateTime)m.Date, 
       EmployeeName = m.Employee.EmployeeName 
      }).ToArray(); 

      //Populate datatable 
      foreach (var matrix in result) 
       table = matrix.ProcessRow(table); 

      Console.Read(); 
     } 

    } 
} 

这将创建与templatenames作为columnames的DataTable。每一行代表一名雇员,并填写相应模板的日期时间。然后,您可以将此数据表传递到您的视图以显示它。

我希望这可以工作!

编辑:我测试了几个分贝值,它似乎工作。有可能使Employeename成为主键而不是列。

0

类(或更改的IEnumerable到IQueryable的,如果你的datacontext仍然存在):

public MyViewModel { 
    IEnumerable<emp> emps; 
    IEnumerable<template> templates; 
} 

控制器:

var emps=db.emps 
    .Include(e=>e.matrices) 
    .Include(e=>e.matrices.template); 
var templates=db.templates; 
var model=new MyViewModel { emps=emps,templates=templates }; 
return model; 

查看:

@model MyViewModel 
<thead><tr> 
@foreach(var template in model.templates) 
{ 
    <th>@template.Name</th> 
} 
</tr></thead> 
<tbody> 
@foreach(var emp in model.emps) 
{ 
    <tr> 
    @foreach(var template in model.templates) 
    { 
    <td> 
     @(emp.matrices.Any(m=>m.templateId==template.templateId)? 
     emp.matrices.First(m=>m.templateId==template.templateId).toString("G"): 
     "") 
    </td> 
    } 
    </tr> 
} 
</tbody>