无法将T-SQL INNER JOIN转换为LINQ-Entities查询

时间:2012-04-11 05:37:27

标签: c# tsql c#-4.0 linq-to-entities inner-join

T-SQL:

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-Entities:

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关键字无法推断出类型参数。

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

我认为您不能将SQL表与内存中的对象列表连接起来,即使这些对象最初来自数据库。

将内存中的对象列表转换为id(整数)列表,并在连接或包含/子选择中使用它。 EF可以在生成SQL时将id列表转换为参数。

答案 1 :(得分: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();

答案 2 :(得分: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();