2012-04-11 56 views
2

T-SQL:无法将T-SQL INNER JOIN到LINQ,查询实体

declare @postlocations table (locationid int) 
insert into @postlocations 
select locationid 
from dbo.PostLocations 
where PostId = 162172 

select t.* 
from dbo.Themes t 
inner join dbo.ThemeLocations tl on t.ThemeId = tl.ThemeId 
inner join @postlocations pl on tl.LocationId = pl.locationid 

LINQ的实体,我至今:

var postLocations = e.SomePost.Locations; // pre-fetched, e.g materialized ICollection<Post> 
var themes = (from t in db.Themes 
      join q in postLocations on t.Locations.Select(l => l.LocationId) equals q.LocationId 
      select t).ToList(); 

但是,编译器是抱怨的join关键字不能推断出类型参数。

任何想法?

+0

为什么你的T-SQL两个独立查询开始?它看起来应该是一个单一的查询。 – 2012-04-11 06:51:19

+0

@Damien_The_Unbeliever - 因为第一个实际上是一个内存集合。相同的源数据,但已经预取。 – RPM1984 2012-04-11 08:07:08

回答

0

编辑

这个怎么样

///your sql query 
select t.* from dbo.Themes t 
inner join dbo.ThemeLocations tl on t.ThemeId = tl.ThemeId 
inner join @postlocations pl on tl.LocationId = pl.locationid 

//linq query for that 
from t in teams 
join from tl in teamlocation on t.themid = tl.ThemeID 
join from pl in postlocation on tl.temeid = pl.temeid 
select t; 

组织

不知道,但你可以通过使用let关键字

var themes = (from t in db.Themes 
       let location = t.Locations 

      join q in postLocations on location.LocationId equals q.LocationId 
      select t).ToList(); 
1

我不尝试一下认为你可以n使用内存对象列表连接SQL表,即使这些对象最初来自数据库。

将内存中的对象列表转换为id(整数)列表,并将其用于连接或Contains/sub-select中。在生成SQL时,EF可以将ID列表转换为参数。

1

加入的问题在于,您暗示的集合LocationIdt.Locations.Select(l => l.LocationId)可以等于一个LocationId。您正尝试将包含位置集合的主题加入到单个位置。

您应该能够通过使用Contains

var themes = (from t in db.Themes 
      join q in postLocations 
      on t.Locations.Select(l => l.LocationId).Contains(q.LocationId) 
      select t).ToList(); 

解决这一问题,或者如果EF抱怨传递postLocations作为参数,你可以尝试

// I'd materialize this but you may not have to 
var postLocationIds = postLocations.Select(p => p.LocationId).ToList(); 

var themes = db.Themes.Where(t => t.Locations.Any(l => 
       postLocationIds.Contains(l.LocationId))).ToList();