用于内部联接的实体框架查询


69

查询的内容是:

select s.* from Service s 
inner join ServiceAssignment sa on sa.ServiceId = s.Id
where  sa.LocationId = 1

在实体框架中?

这是我写的:

 var serv = (from s in db.Services
                join sl in Location on s.id equals sl.id
                where sl.id = s.id
                select s).ToList();

但这是错误的。有人可以引导我走这条路吗?



1
您正在使用赋值=而不是==where子句中进行比较。另外,如果您已经加入该字段,则不需要。
Sergey Berezovskiy

3
where sl.id = s.id加入条件不是多余的吗?
cp.engr 2015年

Answers:


98
from s in db.Services
join sa in db.ServiceAssignments on s.Id equals sa.ServiceId
where sa.LocationId == 1
select s

哪里db是你的DbContext。生成的查询将类似于(EF6示例):

SELECT [Extent1].[Id] AS [Id]
       -- other fields from Services table
FROM [dbo].[Services] AS [Extent1]
INNER JOIN [dbo].[ServiceAssignments] AS [Extent2]
    ON [Extent1].[Id] = [Extent2].[ServiceId]
WHERE [Extent2].[LocationId] = 1

2
那不是左外连接吗?
乔纳森·伍德

3
@JonathanWood不,那是内部联接。左外部联接将由组联接生成。
Sergey Berezovskiy 2014年

我们可以在db.Services中使用from来连接s.Id上的db.ServiceAssignments中的sa是否等于sa.ServiceId || s.Id等于null,其中sa.LocationId == 1选择s
r.hamd

非常感谢...我用过List<Item> items = (..your code..).toList();

4
@JoSmo如果您具有导航属性(来自下面的示例),则可以使用Method语法没问题。但是,如果没有,它将看起来像这样(非常有毛):db.Services.Join(db.ServiceAssignments, s=>s.Id, sa=>sa.ServiceId, (s,sa)=> new{service = s, alert=sa}).Where(ssa=>ssa.alert.LocationId ==1).Select(ssa=>ssa.service);
迈克尔·布莱克本

59

如果有人对Method语法感兴趣,那么如果您有一个导航属性,那就很简单:

db.Services.Where(s=>s.ServiceAssignment.LocationId == 1);

如果不这样做,除非Join()我不知道有一些替代,否则我认为它看起来很粗糙(而且我是Method语法的纯粹主义者):

db.Services.Join(db.ServiceAssignments, 
     s => s.Id,
     sa => sa.ServiceId, 
     (s, sa) => new {service = s, asgnmt = sa})
.Where(ssa => ssa.asgnmt.LocationId == 1)
.Select(ssa => ssa.service);

如果FK到ServiceAssignment碰巧可以为空,这将不起作用,对吗?
Cardin'7

3
在这种情况下,@ Cardin我建议使用C#6?操作员。如果没有,只需在使用navigation属性之前检查null。通常,您不会在示例中添加一堆防御性代码,以免混淆要点。如果FK可为空,则它将看起来像这样:(C#6)db.Services.Where(s=>s?.ServiceAssignment.LocationId == 1);或在C#5中这样:db.Services.Where(s=>s.ServiceAssignment != null && s.ServiceAssignment.LocationId == 1);
Michael Blackburn

1
@MichaelBlackburn这是真的!这是可以理解的。感谢您的澄清。:)
Cardin

7

您可以使用导航属性(如果可用)。它在SQL中产生内部联接。

from s in db.Services
where s.ServiceAssignment.LocationId == 1
select s
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.