How to do joins in LINQ on multiple fields in single join

前端 未结 13 1927
小鲜肉
小鲜肉 2020-11-22 17:02

I need to do a LINQ2DataSet query that does a join on more than one field (as

var result = from x in entity
join y in entity2 
       on x.field1 = y.field1          


        
相关标签:
13条回答
  • 2020-11-22 17:57
    var result = from x in entity
                 join y in entity2
                 on new { X1= x.field1, X2= x.field2 } equals new { X1=y.field1, X2= y.field2 }
                 select new 
                 {
                   /// Columns
                  };
    
    0 讨论(0)
  • you could do something like (below)

    var query = from p in context.T1
    
            join q in context.T2
    
            on
    
            new { p.Col1, p.Col2 }
    
            equals
    
             new { q.Col1, q.Col2 }
    
            select new {p...., q......};
    
    0 讨论(0)
  • 2020-11-22 18:03

    I used tuples to do that, this is an example for two columns :

     var list= list1.Join(list2,
                           e1 => (e1.val1,e1.val2),
                           e2 => (e2.val1,e2.val2),
                           (e1, e2) => e1).ToList();
    
    0 讨论(0)
  • 2020-11-22 18:04
    var result = from x in entity
       join y in entity2 on new { x.field1, x.field2 } equals new { y.field1, y.field2 }
    
    0 讨论(0)
  • 2020-11-22 18:06

    The solution with the anonymous type should work fine. LINQ can only represent equijoins (with join clauses, anyway), and indeed that's what you've said you want to express anyway based on your original query.

    If you don't like the version with the anonymous type for some specific reason, you should explain that reason.

    If you want to do something other than what you originally asked for, please give an example of what you really want to do.

    EDIT: Responding to the edit in the question: yes, to do a "date range" join, you need to use a where clause instead. They're semantically equivalent really, so it's just a matter of the optimisations available. Equijoins provide simple optimisation (in LINQ to Objects, which includes LINQ to DataSets) by creating a lookup based on the inner sequence - think of it as a hashtable from key to a sequence of entries matching that key.

    Doing that with date ranges is somewhat harder. However, depending on exactly what you mean by a "date range join" you may be able to do something similar - if you're planning on creating "bands" of dates (e.g. one per year) such that two entries which occur in the same year (but not on the same date) should match, then you can do it just by using that band as the key. If it's more complicated, e.g. one side of the join provides a range, and the other side of the join provides a single date, matching if it falls within that range, that would be better handled with a where clause (after a second from clause) IMO. You could do some particularly funky magic by ordering one side or the other to find matches more efficiently, but that would be a lot of work - I'd only do that kind of thing after checking whether performance is an issue.

    0 讨论(0)
  • 2020-11-22 18:07

    I think a more readable and flexible option is to use Where function:

    var result = from x in entity1
                 from y in entity2
                     .Where(y => y.field1 == x.field1 && y.field2 == x.field2)
    

    This also allows to easily change from inner join to left join by appending .DefaultIfEmpty().

    0 讨论(0)
提交回复
热议问题