C# SQL到LINQ以获取与所有值匹配的所有记录
如何将此查询转换为linq c代码:C# SQL到LINQ以获取与所有值匹配的所有记录,c#,sql,asp.net-mvc,linq,C#,Sql,Asp.net Mvc,Linq,如何将此查询转换为linq c代码: SELECT k1.Ad_Id FROM KeywordAdCategories k1, KeywordAdCategories k2 WHERE k1.Keyword_Id = (SELECT Id FROM keywords WHERE name = 'ALFA') AND k2.Keyword_Id = (SELECT Id FROM keywords WHERE name = '145') AND k1.Ad_Id = k2.Ad_Id idei
SELECT k1.Ad_Id FROM KeywordAdCategories k1, KeywordAdCategories k2
WHERE k1.Keyword_Id = (SELECT Id FROM keywords WHERE name = 'ALFA')
AND k2.Keyword_Id = (SELECT Id FROM keywords WHERE name = '145')
AND k1.Ad_Id = k2.Ad_Id
ideia是基于关键字的数量构建一个动态查询,在示例中,关键字的数量可以是N,它们是2:ALFA和145
谢谢
编辑:
关键词类别模型:
public class KeywordAdCategory
{
[Key]
[Column("Keyword_Id", Order = 0)]
public int Keyword_Id { get; set; }
[Key]
[Column("Ad_Id", Order = 1)]
public int Ad_Id { get; set; }
[Key]
[Column("Category_Id", Order = 2)]
public int Category_Id { get; set; }
}
关键词模型:
public class Keyword
{
// Primary properties
public int Id { get; set; }
public string Name { get; set; }
}
如果我有5个关键字,我会得到:
SELECT k1.Ad_Id FROM KeywordAdCategories k1, KeywordAdCategories k2, KeywordAdCategories k3, KeywordAdCategories k4, KeywordAdCategories k5
WHERE k1.Keyword_Id = (SELECT Id FROM keywords WHERE name = 'KEYWORD1')
AND k2.Keyword_Id = (SELECT Id FROM keywords WHERE name = 'KEYWORD2')
AND k1.Ad_Id = k2.Ad_Id
AND k3.Keyword_Id = (SELECT Id FROM keywords WHERE name = 'KEYWORD3')
AND k2.Ad_Id = k3.Ad_Id
AND k4.Keyword_Id = (SELECT Id FROM keywords WHERE name = 'KEYWORD4')
AND k3.Ad_Id = k4.Ad_Id
AND k5.Keyword_Id = (SELECT Id FROM keywords WHERE name = 'KEYWORD5')
AND k4.Ad_Id = k5.Ad_Id
通过此方法运行所有关键字id,您将获得相应的广告id。我建议您阅读LINQ。一旦你了解了它,它就是一个很棒的工具,学习起来并不难,尽管一开始它可能看起来有点吓人。Pluralsight.com有很多很好的视频,很容易掌握和学习:
List<string> keywordnames = new List<string>();
// populate keywordsnames list
IQueryable<int> AdIds = from k in KeywordAdCategories
where
(from kw in Keywords where keywordnames.Contains(kw.name) select kw.id)
.Contains(k.keyword_id)
select k.Ad_Id;
或
这比我第一次看到它时想的要复杂得多,所以我可能想得太多了。但我相信有一个解决方案会对你有用:
var keywordList = new List<string>();
keywordList.Add("ALFA");
keywordList.Add("145");
var results = KeywordAdCategories.Select (kac => kac.Ad_Id).Distinct()
.Select (a =>
new
{
AdId=a,
Keywords=KeywordAdCategories.Where(kac => kac.Ad_Id == a).Select(kac => kac.Keyword_Id)
})
.Where(ac => ac.Keywords.Intersect(Keywords.Where(kw => keywordList.Contains(kw.Name)).Select (kw => kw.Id)).Count() == keywordList.Count())
.Select (ac => ac.AdId);
当然,这可能更容易从您的ad表中的一个不同的select中检索,但我只尝试使用您定义的内容
接下来,我将每个广告id及其相关关键字集合选择到匿名类型对象列表中:
.Select (a =>
new
{
AdId=a,
Keywords=KeywordAdCategories.Where(kac => kac.Ad_Id == a).Select(kac => kac.Keyword_Id)
})
接下来,我只将结果过滤到包含关键字集合的对象,这些关键字集合与我们的关键字列表相交,并且结果元素的数量与我们的关键字列表相同
.Where(ac => ac.Keywords.Intersect(Keywords.Where(kw => keywordList.Contains(kw.Name)).Select (kw => kw.Id)).Count() == keywordList.Count())
最后我只选择了结果的广告id
.Select (ac => ac.AdId);
如果您感兴趣,这里是emmited sql
-- Region Parameters
DECLARE @p0 NVarChar(1000) = 'ALFA'
DECLARE @p1 NVarChar(1000) = '145'
DECLARE @p2 Int = 2
-- EndRegion
SELECT [t1].[Ad_Id]
FROM (
SELECT DISTINCT [t0].[Ad_Id]
FROM [KeywordAdCategories] AS [t0]
) AS [t1]
WHERE ((
SELECT COUNT(*)
FROM (
SELECT DISTINCT [t2].[Keyword_Id]
FROM [KeywordAdCategories] AS [t2]
WHERE (EXISTS(
SELECT NULL AS [EMPTY]
FROM [Keywords] AS [t3]
WHERE ([t2].[Keyword_Id] = [t3].[Id]) AND ([t3].[Name] IN (@p0, @p1))
)) AND ([t2].[Ad_Id] = [t1].[Ad_Id])
) AS [t4]
)) = @p2
我确信有更优雅的方法来完成您想要做的事情,但我想看看是否可以在一个linq查询中实现这一切。希望这能有所帮助。您的C类是什么样子的?另外,你能举一个例子说明如果关键字的数量是5,SQL会是什么样子吗?我真的不明白为什么关键字ADCategories表被使用了两次。。。可能有更好的方法来编写此SQL,这将导致更好的LINQ示例。@ɹǝʇǝd我认为SQL也可以重写得更好。然而,这个问题指出,更干净的解决方案性能较差:@Peter我只是用更多信息编辑了这个问题,这没有考虑和。这将是一个更具建设性的评论,而不是仅仅否决一个答案。答案是错误的,所以我两者都做了。这就是否决投票的意义所在,以确保人们意识到什么时候答案是错的。如果接近,我不会投反对票,但如果它完全错了,那么我的代码是基于给出的信息。他有一些关键字ID的列表,他可以在其中循环并为每次迭代运行该方法。我不会说这是错的,我会说这是另一种方法。谢谢,但你的答案是返回只包含一个关键字的广告Id,目标是获取包含所有关键字的广告Idkeywords@Patrick,在进行字符串比较时,请仔细检查关键字名称是否填充了您要查找的所有名称,以及是否考虑了大小写敏感度。另外,在我最近编辑的第二个例子中,我尝试了,但即使是第二个例子仍然返回所有有一个关键字或顺序的广告,而不是两者都返回。谢谢!它起作用了!您是否有可能将此代码与此代码合并:?
.Where(ac => ac.Keywords.Intersect(Keywords.Where(kw => keywordList.Contains(kw.Name)).Select (kw => kw.Id)).Count() == keywordList.Count())
.Select (ac => ac.AdId);
-- Region Parameters
DECLARE @p0 NVarChar(1000) = 'ALFA'
DECLARE @p1 NVarChar(1000) = '145'
DECLARE @p2 Int = 2
-- EndRegion
SELECT [t1].[Ad_Id]
FROM (
SELECT DISTINCT [t0].[Ad_Id]
FROM [KeywordAdCategories] AS [t0]
) AS [t1]
WHERE ((
SELECT COUNT(*)
FROM (
SELECT DISTINCT [t2].[Keyword_Id]
FROM [KeywordAdCategories] AS [t2]
WHERE (EXISTS(
SELECT NULL AS [EMPTY]
FROM [Keywords] AS [t3]
WHERE ([t2].[Keyword_Id] = [t3].[Id]) AND ([t3].[Name] IN (@p0, @p1))
)) AND ([t2].[Ad_Id] = [t1].[Ad_Id])
) AS [t4]
)) = @p2