2010-11-02 74 views
0

請幫助我在其中一個場景中,我被困住了。Linq交叉連接查詢嵌套列表

它是這樣的。

  1. 使用PropertyGrid動態創建的列表和列表中的字段(內部表)列表。

    BindingList<Table> table = new BindingList<Table>();   
    [Serializable] 
    [TypeConverter(typeof(TableConverter))] 
    public class Table { 
    private string _name = string.Empty; 
    private HeaderCollection _hc = new HeaderCollection(); 
    private BindingList<Fields> _fc = new BindingList<Fields>(); 
    public Guid key; 
    public Table() { 
        key = Guid.NewGuid(); 
    } 
    
    
    [DisplayName("Table Fields"), Editor(typeof(FieldCollectionEditor), 
    typeof(UITypeEditor))] 
    public BindingList<Fields> Fields { 
        get { return _fc; } 
        set { _fc = value; } 
    } 
    [DisplayName("Table Header")] 
    public HeaderCollection Headers { 
        get { return _hc; } 
        set { _hc = value; } 
    } 
    
    
    [DisplayName("Table Name")] 
    public string Name { 
        get { return _name; } 
        set { _name = value; } 
        } 
    } 
    
  2. Field類定義

    [Serializable] 
    public class Fields { 
    private string _name = string.Empty; 
    public Guid Key; 
    private List<string> _value = new List<string>(); 
    
    
    [Browsable(false)] 
    public List<string> Value { 
        get { return _value; } 
        set { _value = value; } 
    }  
    
    
    public Fields() { 
        Key = Guid.NewGuid(); 
    } 
    
    
    [DisplayName("Field Name")] 
    public string Name { 
        get { return _name; } 
        set { _name = value; } 
    } 
    
    
    [DisplayName("Map")] 
    public bool Map { 
        get; 
        set; 
        } 
    } 
    
  3. Field類包含字符串列表,以容納一個或多個值。

我的問題是:需要交叉連接所有值beloging到表中的所有字段並以表格格式顯示數據。 我已經使用了這個查詢,但是這不起作用,因爲它會逐個提取值,而我需要一次性從所有字段的所有值進行coross連接。

var result = table.SelectMany(
    tbl => tbl.Fields.SelectMany(
     f => f.Value.Select(v => new { i = v }))); 

例如 可以說:

F1 has Value11 
F2 has Value21 
F3 has Value31 and Value 32 
F4 has Value41, Value42 and Value43 

結果應該是在此格式爲每個表和所有字段值。

Value11 Value21 Value 31 Value 41 
Value11 Value21 Value 31 Value 42 
Value11 Value21 Value 31 Value 43 
Value11 Value21 Value 32 Value 41 
Value11 Value21 Value 32 Value 42 
Value11 Value21 Value 32 Value 43 

讓我詳細說明這一點。例如,如果我們有

List<string> master = new List<string>(); 
List<string> child = new List<string>(); 
List<string> child1 = new List<string>(); 
List<string> child2 = new List<string>(); 
and a Linq query to fetch out 

var q = from m in master 
     from c1 in child1 
     from c in child 
     from c2 in child2 
     select new { m, c, c1, c2 }; 

我正好需要這樣寫上面的查詢獲取了字段值,但字段動態生成的問題,因此它們的值裏面,所以我需要某種recussive方法或linq過程來獲得上面示例中提供的結果。

回答

2

你似乎有一個結構,清除所有其他細節:

  • 表具有字段集合
  • 字段有值

的集合,並希望有一個結果是是所有的價值觀跨越所有領域。我會(使用兩個查詢來獲得這兩個循環)跨越自身的各個領域取得的所有值的集合開始:

var values = from v in (from f in Table.Fields select f.Values) 
      select v; 

,然後進行連接:

var res = from v in values 
      from f in Table.Fields 
      select new { 
      Field = f, 
      Value = v 
      }; 
+0

這爲我場的x值,而不是我需要的價值X值(跨所有領域)。 – user885412 2010-11-03 03:48:15

+0

@Buzzy:你的回答應該作爲對問題的修改來完成(因爲它正在擴大/改進問題,而不是回答)。第二:我必須考慮這一點(想到遞歸),第三:Eric Lippert已經解決了我的問題:http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/計算笛卡爾的產品與LINQ.aspx – Richard 2010-11-03 08:58:24

+0

謝謝理查德,我要通過埃裏克利珀博客,我會回來,這並不能解決我的問題 – user885412 2010-11-03 10:34:49

0

感謝您即時迴應 我試過你的方法,但仍然沒有以tabluar格式獲取值。讓我再次清楚細節。

咱們說

Field1 has Value11 
Field2 has Value21 
Field3 has Value31 and Value32 
Field4 has Value41, Value42 and Value43 

所有這些領域都屬於單表。

現在交叉連接後,結果應該如下所示。

Value11 Value21 Value31 Value41 
Value11 Value21 Value31 Value42 
Value11 Value21 Value31 Value43 
Value11 Value21 Value32 Value41 
Value11 Value21 Value32 Value42 
Value11 Value21 Value32 Value43 

....... 
------ 

etc. 

感謝

嗡嗡

1

這應包括在第一篇文章的主/子樣本:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var listofInts = new List<List<int>>(3); 
     listofInts.Add(new List<int>{1, 2, 3}); 
     listofInts.Add(new List<int> { 4,5,6 }); 
     listofInts.Add(new List<int> { 7,8,9,10 }); 

     var temp = CrossJoinLists(listofInts); 
     foreach (var l in temp) 
     { 
      foreach (var i in l) 
       Console.Write(i + ","); 
      Console.WriteLine(); 
     } 
    } 

    private static IEnumerable<List<T>> CrossJoinLists<T>(IEnumerable<List<T>> listofObjects) 
    { 
     var result = from obj in listofObjects.First() 
        select new List<T> {obj}; 

     for (var i = 1; i < listofObjects.Count(); i++) 
     { 
      var iLocal = i; 
      result = from obj in result 
        from obj2 in listofObjects.ElementAt(iLocal) 
        select new List<T>(obj){ obj2 }; 
     } 

     return result; 
    } 
}