如何在 LINQ 中对单个连接中的多个字段进行连接
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/373541/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to do joins in LINQ on multiple fields in single join
提问by johnc
I need to do a LINQ2DataSet query that does a join on more than one field (as
我需要做一个 LINQ2DataSet 查询,该查询在多个字段上进行连接(如
var result = from x in entity
join y in entity2
on x.field1 = y.field1
and
x.field2 = y.field2
I have yet found a suitable solution (I can add the extra constraints to a where clause, but this is far from a suitable solution, or use thissolution, but that assumes an equijoin).
我还没有找到合适的解决方案(我可以在 where 子句中添加额外的约束,但这远不是一个合适的解决方案,或者使用这个解决方案,但假设是等值联接)。
Is it possible in LINQ to join on multiple fields in a single join?
在 LINQ 中是否可以在单个连接中加入多个字段?
EDIT
编辑
var result = from x in entity
join y in entity2
on new { x.field1, x.field2 } equals new { y.field1, y.field2 }
is the solution I referenced as assuming an equijoin above.
是我在上面假设 equijoin 时引用的解决方案。
Further EDIT
进一步编辑
To answer criticism that my original example was an equijoin, I do acknowledge that, My current requirement is for an equijoin and I have already employed the solution I referenced above.
为了回答关于我的原始示例是 equijoin 的批评,我承认,我目前的要求是 equijoin,并且我已经采用了我上面引用的解决方案。
I am, however, trying to understand what possibilities and best practices I have / should employ with LINQ. I am going to need to do a Date range query join with a table ID soon, and was just pre-empting that issue, It looks like I shall have to add the date range in the where clause.
但是,我正在尝试了解我拥有/应该使用 LINQ 的可能性和最佳实践。我很快需要对表 ID 进行日期范围查询连接,并且只是在解决这个问题,看来我必须在 where 子句中添加日期范围。
Thanks, as always, for all suggestions and comments given
一如既往地感谢您提出的所有建议和意见
采纳答案by Jon Skeet
The solution with the anonymous type should work fine. LINQ canonly represent equijoins (with join clauses, anyway), and indeed that's what you've said you want to express anyway based on your original query.
匿名类型的解决方案应该可以正常工作。LINQ可以只表示等值连接(用联接子句,反正),而事实上,你已经什么的说你要根据你的原始查询反正表达。
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 reallywant 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.
编辑:回应问题中的编辑:是的,要进行“日期范围”连接,您需要改用 where 子句。它们在语义上实际上是等效的,因此这只是可用优化的问题。Equijoins 通过基于内部序列创建查找来提供简单的优化(在 LINQ to Objects 中,包括 LINQ to DataSets) - 将其视为从键到匹配该键的条目序列的哈希表。
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.
在日期范围内这样做有点困难。但是,根据“日期范围连接”的确切含义,您可能可以做类似的事情- 如果您计划创建日期的“带”(例如每年一个),以便在同一年(但不在同一日期)应该匹配,然后您只需使用该乐队作为键就可以做到。如果它更复杂,例如连接的一侧提供一个范围,连接的另一侧提供单个日期,如果它落在该范围内,则匹配,最好用where
子句处理(一秒钟后)from
条款)国际海事组织。您可以通过订购一侧或另一侧来更有效地找到匹配项来做一些特别时髦的魔术,但这将是一项大量工作 - 我只会在检查性能是否有问题后才做这种事情。
回答by KristoferA
var result = from x in entity
join y in entity2 on new { x.field1, x.field2 } equals new { y.field1, y.field2 }
回答by tvanfosson
Using the join operator you can only perform equijoins. Other types of joins can be constructed using other operators. I'm not sure whether the exact join you are trying to do would be easier using these methods or by changing the where clause. Documentation on the join clause can be found here. MSDN has an article on join operationswith multiple links to examples of other joins, as well.
使用连接运算符只能执行等值连接。可以使用其他运算符构造其他类型的连接。我不确定使用这些方法或更改 where 子句是否会更轻松地进行您尝试进行的确切连接。可以在此处找到有关 join 子句的文档。MSDN 上有一篇关于连接操作的文章,其中还有指向其他连接示例的多个链接。
回答by Perpetualcoder
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......};
回答by user2745564
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)
this works for me
这对我有用
回答by niieani
Just to complete this with an equivalent method chain syntax:
只需使用等效的方法链语法完成此操作:
entity.Join(entity2, x => new {x.Field1, x.Field2},
y => new {y.Field1, y.Field2}, (x, y) => x);
While the last argument (x, y) => x
is what you select (in the above case we select x
).
而最后一个参数(x, y) => x
是您选择的(在上述情况下我们选择x
)。
回答by user3966657
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
};
回答by RealNapster
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 }
You need to do this, if the column names are different in two entities.
如果两个实体中的列名称不同,则需要执行此操作。
回答by Mahesh
If the field name are different in entities
如果实体中的字段名称不同
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});
回答by Alexei
I think a more readable and flexible option is to use Where function:
我认为更具可读性和灵活性的选择是使用 Where 函数:
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().
这也允许通过附加 .DefaultIfEmpty() 轻松地从内连接更改为左连接。