我需要做一个LINQ2DataSet查询,对多个字段(如

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

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

在LINQ中是否可以在一个连接中连接多个字段?

EDIT

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

是我在上面假设等联时引用的解决方案。

进一步的编辑

为了回答批评,我原来的例子是一个等量连接,我承认,我目前的要求是一个等量连接,我已经采用了我上面提到的解决方案。

然而,我正在尝试了解我已经/应该使用LINQ的可能性和最佳实践。我将需要做一个日期范围查询连接与表ID很快,只是先发制人的问题,看起来我必须在where子句中添加日期范围。

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


当前回答

我认为一个更具可读性和灵活性的选项是使用Where函数:

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

这也允许通过添加. defaultifempty()轻松地将内连接更改为左连接。

其他回答

您可以这样做(如下所示)

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

如果两个实体中的列名不同,则需要这样做。

使用联接运算符,只能执行相等联接。其他类型的连接可以使用其他操作符构造。我不确定使用这些方法或更改where子句是否会更容易执行您试图执行的确切连接。关于join子句的文档可以在这里找到。MSDN有一篇关于连接操作的文章,其中还有指向其他连接示例的多个链接。

用一个等价的方法链语法来完成这个:

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

而最后一个参数(x, y) => x是你选择的(在上面的情况下,我们选择x)。

使用匿名类型的解决方案应该可以正常工作。LINQ只能表示等连接(使用连接子句),实际上,这正是您根据原始查询想要表达的内容。

如果您因为某些特定的原因而不喜欢匿名类型的版本,那么您应该解释这个原因。

如果你想做的事情与你最初要求的不同,请举例说明你真正想做的事情。

编辑:回答问题中的编辑:是的,要做一个“日期范围”连接,你需要使用一个where子句。它们在语义上是等效的,所以这只是一个可用的优化问题。等连接提供了简单的优化(在LINQ到对象中,包括LINQ到数据集),通过创建基于内部序列的查找-可以将其视为从键到匹配该键的条目序列的哈希表。

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.