我对以下查询感到茫然,这是普通T-SQL中的花生。
我们有三个物理表:
现在我要做的是获取一个链接到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'...
答案 0 :(得分:27)
此解决方案的关键是在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.
}