Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# SQL到LINQ以获取与所有值匹配的所有记录_C#_Sql_Asp.net Mvc_Linq - Fatal编程技术网

C# SQL到LINQ以获取与所有值匹配的所有记录

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

如何将此查询转换为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
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