2011-07-18 19 views
3

我想获得一个连接查询的结果与多个选择到数据表,没有选择每个领域分开。通用方法来获取LINQ结果到数据表选择新的具有多个选择

这是设置:

public class info 
{ 
    public int id {get;set;} 
    public int linked { get; set; } 
    public int someNumber { get; set; } 
} 

     List<info> myInfoList = new List<info>(); 
     myInfoList.Add(new info { id = 20110102, linked = 1, someNumber = 1 }); 
     myInfoList.Add(new info { id = 20110103, linked = 2, someNumber = 3 }); 
     myInfoList.Add(new info { id = 20110104, linked = 3, someNumber = 4 }); 
     myInfoList.Add(new info { id = 20110105, linked = 4, someNumber = 5 }); 
     myInfoList.Add(new info { id = 20110106, linked = 5, someNumber = 6 }); 
     myInfoList.Add(new info { id = 20110107, linked = 1, someNumber = 1 }); 
     myInfoList.Add(new info { id = 20110108, linked = 2, someNumber = 2 }); 
     myInfoList.Add(new info { id = 20110109, linked = 3, someNumber = 3 }); 
     myInfoList.Add(new info { id = 20110110, linked = 4, someNumber = 1 }); 
     myInfoList.Add(new info { id = 20110111, linked = 1, someNumber = 1 }); 
     myInfoList.Add(new info { id = 20110112, linked = 1, someNumber = 1 }); 
     myInfoList.Add(new info { id = 20110113, linked = 2, someNumber = 1 }); 
     myInfoList.Add(new info { id = 20110114, linked = 2, someNumber = 1 }); 
     myInfoList.Add(new info { id = 20110115, linked = 3, someNumber = 1 }); 

     List<info> myInfoList2 = new List<info>(); 
     myInfoList2.Add(new info { id = 20110102, linked = 1, someNumber = 1 }); 
     myInfoList2.Add(new info { id = 20110102, linked = 2, someNumber = 3 }); 
     myInfoList2.Add(new info { id = 20110102, linked = 3, someNumber = 4 }); 

     List<info> myInfoList3 = new List<info>(); 
     myInfoList3.Add(new info { id = 20110102, linked = 1, someNumber = 1 }); 
     myInfoList3.Add(new info { id = 20110103, linked = 2, someNumber = 3 }); 
     myInfoList3.Add(new info { id = 20110112, linked = 3, someNumber = 4 }); 


     var outerJoinTest = from x in myInfoList 
          join y in myInfoList2 
          on x.linked equals y.linked 
          into temp 
          from t in temp.DefaultIfEmpty() 
          join z in myInfoList3 
          on x.id equals z.id 
          into temp2 
          from t2 in temp2.DefaultIfEmpty() 
          select new { x, t, t2 }; 

我通常使用这种方法来LINQ查询转换为数据表:

 private DataTable LINQToDataTable<T>(IEnumerable<T> varlist) 
    { 

     DataTable dtReturn = new DataTable(); 

     PropertyInfo[] columnNames = null; 

     if (varlist == null) return dtReturn; 

     foreach (T rec in varlist) 
     { 
      if (columnNames == null) 
      { 
       columnNames = ((Type)rec.GetType()).GetProperties(); 
       foreach (PropertyInfo pi in columnNames) 
       { 
        Type colType = pi.PropertyType; 

        if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>))) 
        { 
         colType = colType.GetGenericArguments()[0]; 
        } 

        dtReturn.Columns.Add(new DataColumn(pi.Name, colType)); 
       } 
      } 

      DataRow dr = dtReturn.NewRow(); 

      foreach (PropertyInfo pi in columnNames) 
      { 
       dr[pi.Name] = pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue 
       (rec, null); 
      } 

      dtReturn.Rows.Add(dr); 
     } 

     return dtReturn; 
    } 

但这种方法不使用多个匿名选择正常工作。

我得到这样的结果:

enter image description here

当我设置的私人数据表LINQToDataTable(IEnumerable的varlist中的)一个破发点,悬停在上面REC我可以看到我想要在数据表中看到的值。

enter image description here

有人可以帮助我改变的方式方法,它输出的结果是这样的:

enter image description here

+0

感谢马里诺添加图片 – user369122

回答

1

怎么是这样的:

private class NestedPropertyInfo 
{ 
    public PropertyInfo Parent { get; set; } 
    public PropertyInfo Child { get; set; } 
    public string Name { get { return Parent.Name + "_" + Child.Name; } } 
} 

private DataTable LINQToDataTable<T>(IEnumerable<T> varlist) 
{ 
    DataTable dtReturn = new DataTable(); 
    NestedPropertyInfo[] columns = null; 

    if (varlist == null) return dtReturn; 

    foreach (T rec in varlist) 
    { 
     if (columns == null) 
     { 
      columns = (
       from p1 in rec.GetType().GetProperties() 
       from p2 in p1.PropertyType.GetProperties() 
       select new NestedPropertyInfo { Parent = p1, Child = p2 } 
       ).ToArray(); 

      foreach (var column in columns) 
      { 
       var colType = column.Child.PropertyType; 

       if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>))) 
       { 
        colType = colType.GetGenericArguments()[0]; 
       } 

       dtReturn.Columns.Add(new DataColumn(column.Name, colType)); 
      } 
     } 

     DataRow dr = dtReturn.NewRow(); 

     foreach (var column in columns) 
     { 
      var parentValue = column.Parent.GetValue(rec, null); 
      var childValue = parentValue == null ? null : column.Child.GetValue(parentValue, null); 
      dr[column.Name] = childValue ?? DBNull.Value; 
     } 

     dtReturn.Rows.Add(dr); 
    } 

    return dtReturn; 
} 

此外,与问题无关,但您应该真的使用集合初始值设定项:

var myInfoList = new List<info> 
{ 
    new info { id = 20110102, linked = 1, someNumber = 1 }, 
    new info { id = 20110103, linked = 2, someNumber = 3 }, 
    new info { id = 20110104, linked = 3, someNumber = 4 }, 
    // ... 
}; 
+0

真棒!这正是我想要的。非常感谢。 Regards, Matthijs – user369122