首页 文章

如何在单个连接中的多个字段上进行LINQ连接

提问于
浏览
213

我需要做一个LINQ2DataSet查询,在多个字段上进行连接(如

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

我还找到了一个合适的解决方案(我可以在where子句中添加额外的约束,但这远不是一个合适的解决方案,或者使用this解决方案,但假设是等值连接) .

LINQ是否可以在单个连接中加入多个字段?

EDIT

var result = from x in entity
             join y in entity2
             on new { x.field1, x.field2 } equals new { y.field1, y.field2 }

我引用的解决方案是假设上面的等值连接 .

进一步 EDIT

为了回答我最初的例子是等值的批评,我确实承认,我目前的要求是等同于我,我已经采用了上面引用的解决方案 .

但是,我试图了解LINQ应该采用/应该采用的可能性和最佳实践 . 我很快就需要使用表ID进行日期范围查询连接,并且只是预先解决了这个问题,看起来我必须在where子句中添加日期范围 .

一如既往地感谢所有建议和意见

12 回答

  • 9

    具有匿名类型的解决方案应该可以正常工作 . LINQ只能表示equijoins(无论如何都有join子句),事实上's what you' ve表示你想根据原始查询表达 .

    如果您因某些特定原因不喜欢具有匿名类型的版本,则应解释该原因 .

    如果你想做的不是你原来要求的事情,请举例说明你真正想做的事情 .

    编辑:回答问题中的编辑:是的,要进行“日期范围”连接,您需要使用where子句 . 它们在语义上是等价的,所以它只是可用优化的问题 . Equijoins通过基于内部序列创建查找,提供简单的优化(在LINQ to Objects中,包括LINQ to DataSets) - 将其视为从key到匹配该键的条目序列的哈希表 .

    使用日期范围执行此操作有点困难 . 但是,根据你所说的"date range join"你可能会做类似的事情 - 如果你更复杂,例如连接的一侧提供一个范围,连接的另一侧提供单个日期,如果它在该范围内,则匹配,使用 where 子句(在第二个 from 子句之后)IMO可以更好地处理 . 你可以通过命令一方或另一方更有效地找到匹配来做一些特别时髦的魔术,但那将是很多工作 - 我只会在检查性能是否是一个问题之后做这种事情 .

  • 7
    var result = from x in entity
       join y in entity2 on new { x.field1, x.field2 } equals new { y.field1, y.field2 }
    
  • 0
    var result = from x in entity1
                 join y in entity2
                 on new { X1= x.field1, X2= x.field2 } equals new { X1=y.field1, X2= y.field2 }
    

    如果两个实体中的列名不同,则需要执行此操作 .

  • 78

    只是用等效的方法链语法来完成它:

    entity.Join(entity2, x => new {x.Field1, x.Field2},
                         y => new {y.Field1, y.Field2}, (x, y) => x);
    

    虽然最后一个参数 (x, y) => x 是您选择的(在上面的例子中我们选择 x ) .

  • -2

    我认为更可读和灵活的选择是使用Where函数:

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

    这也允许通过附加.DefaultIfEmpty()轻松地从内连接更改为左连接 .

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

    使用join运算符,您只能执行equijoins . 可以使用其他运算符构造其他类型的连接 . 我不确定使用这些方法或更改where子句,您尝试进行的确切连接是否更容易 . 有关join子句的文档可以在here找到 . MSDN还有一个article on join operations,其中包含指向其他连接示例的多个链接 .

  • 61

    你可以做点什么(下面)

    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......};
    
  • 1

    如果实体中的字段名称不同

    var result = from x in entity
       join y in entity2 on 
              new {
                    field1=   x.field1,
                   field2 =  x.field2 
                 } 
              equals
             new { 
                    field1= y.field1,
                    field2=  y.myfield
                  }
    select new {x,y});
    
  • 0

    声明一个Class(Type)来保存您想要加入的元素 . 在下面的示例中声明 JoinElement

    public class **JoinElement**
    {
        public int? Id { get; set; }
        public string Name { get; set; }
    
    }
    
    results = from course in courseQueryable.AsQueryable()
                      join agency in agencyQueryable.AsQueryable()
                       on new **JoinElement**() { Id = course.CourseAgencyId, Name = course.CourseDeveloper } 
                       equals new **JoinElement**() { Id = agency.CourseAgencyId, Name = "D" } into temp1
    
  • 45

    作为一个完整的方法链,看起来像这样:

    lista.SelectMany(a => listb.Where(xi => b.Id == a.Id && b.Total != a.Total),
                    (a, b) => new ResultItem
                    {
                        Id = a.Id,
                        ATotal = a.Total,
                        BTotal = b.Total
                    }).ToList();
    
  • 111
    from d in db.CourseDispatches
                                 join du in db.DispatchUsers on d.id equals du.dispatch_id
                                 join u in db.Users on du.user_id equals u.id
                                 join fr in db.Forumreports on (d.course_id + '_' + du.user_id)  equals  (fr.course_id + '_'+ fr.uid)
    

    这对我有用

相关问题