开发者

Linq cross join query for nested List

Please do help me out in one of the scenario, where I got stucked.

It goes like this.

  1. A dynamically created List of table and List of Fields( inside Table ) using 开发者_Python百科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 class definition

    [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 class contain List of string to hold one or more value.

My Problem is : Need to cross join all values beloging to all fields from a table and display the data in tabular format. I have used this query, but this does not work as it fetch out the values one by one, instead i need a coross join of all values from all fields at one go.

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

For Example, Lets say :

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

The result should be in this format for each table and all fields’ value.

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

Let me elaborate this a little bit more. For example if we have

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

I exactly need to write the above query like this to fetch out field values but the problem is fields are generated dynamically and so the values inside it, hence i need some sort of recussive method or linq procedure to yeild the result as provided in sample above.


You seem to have a structure, removing all other details:

  • Table has a collection of fields
  • Field has a collection of values

And want to have a result which is all values cross all fields. I would start with getting a collection of all values across all fields on its own (using two queries to get both loops):

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

And then do the join:

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


This should cover your master/child sample in the first post:

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


Thanks for you immediate response I tried your approach but still not gettting values in tabluar format. Let me clear the details once again.

Let say

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

All these fields belong to single table.

Now after Cross join, the result should be like this as hown below.

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.  

Thanks

Buzzy

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜