Linq to Entities多对多选择查询

时间:2009-07-08 13:13:31

标签: c# tsql linq-to-entities

我对以下查询感到茫然,这是普通T-SQL中的花生。

我们有三个物理表:

  • Band(PK = BandId)
  • MusicStyle(PK = MuicStyleId)
  • BandMusicStyle(PK = BandId + MusicStyleId,FK = BandId,MusicStyleId)

现在我要做的是获取一个链接到Band的MusicStyles列表,其中包含一个特定搜索字符串的名称。带名应该在结果中。

T-SQL就是这样的:

SELECT b.Name, m.ID, m.Name, m.Description
FROM Band b 
INNER JOIN BandMusicStyle bm on b.BandId = bm.BandId
INNER JOIN MusicStyle m on bm.MusicStyleId = m.MusicStyleId
WHERE b.Name like '%@searchstring%'

我如何在Linq To Entities中写这个?

PS:由于某些奇怪的原因,StackOverflow不允许搜索字符串'many to many'...

4 个答案:

答案 0 :(得分:27)

事实证明这比看起来要简单得多。我使用以下博文解决了这个问题:http://weblogs.asp.net/salimfayad/archive/2008/07/09/linq-to-entities-join-queries.aspx

此解决方案的关键是在musicstyle集合的Bands子集上应用bandname的过滤器。

var result=(from m in _entities.MusicStyle 
            from b in m.Band
            where b.Name.Contains(search)
            select new {
                BandName = b.Name,
                m.ID,
                m.Name,
                m.Description
            });

注意该行

from b IN m.Band

这可确保您只对具有音乐风格的乐队进行过滤。

感谢您的回答,但没有一个能解决我的问题。

答案 1 :(得分:4)

在Linq中,实际上您不需要编写任何内容,如果在SQL数据库的图中定义关系并使用该实用程序生成,则会自动构建对象层次结构。这意味着,如果你这样做:

var bands = from ms in db.MusicStyle
            let b = ms.Bands
            where b.Name.Contains(SEARCHSTRING)
            select new {
                b.Name, ms.Name, 
                ms.ID, ms.Description};

如果您查看生成的实体类,BandMusicStyle不应显示为LINQ to Entities认为Band和MusicStyle是多对多的,并且该表不是必需的。

看看它是否有效?

答案 2 :(得分:1)

您可以执行上述操作,但是一旦您开始迭代它们并且过滤在内存而不是数据库中完成,这将带回所有结果。

我认为你要找的只是几个连接?

var q = from b in db.Bands
join bm in db.BandMusicStyle on on b.BandId equals bm.BandId
join ms in db.MusicStyle on bm.MusicStyleId equals m.MusicStyleId
where b.Name.Contains(searchString)
select new { b.Name, ms.ID, ms.Name, ms.Description };
无论如何,

或其他相关的东西

答案 3 :(得分:0)

from ms in Context.MusicStyles
where ms.Bands.Any(b => b.Name.Contains(search))
select ms;

这只会返回样式,这是您的问题所要求的。另一方面,示例SQL返回样式和波段。为此,我会这样做:

from b in Context.Bands
where b.Name.Contains(search)
group b by band.MusicStyle into g
select new {
    Style = g.Key,
    Bands = g
}

from b in Context.Bands
where b.Name.Contains(search)
select new {
    BandName = b.Name,
    MusicStyleId = b.MusicStyle.Id,
    MusicStyleName = b.MusicStyle.Name,
    // etc.
}