【问题标题】:How to write SQL SELECT INNER JOIN with multiple conditions (with LIKE) query to LINQ to SQL如何编写具有多个条件(使用 LIKE)查询的 SQL SELECT INNER JOIN 到 LINQ to SQL
【发布时间】:2011-09-04 21:19:48
【问题描述】:

我一直在寻找如何做到这一点,我发现了一些接近的东西,但不是我想要的。我想知道这是否也可以帮助其他人,但我真的可以使用帮助。我有一个非常简单的 SELECT 语句,我需要将其转换为 LINQ to SQL 以加快我们软件中的搜索速度:

SELECT  Animals.*
FROM    Animals 
        INNER JOIN AnimalAliases
        ON  Animals.AnimalID = AnimalAliases.AnimalID 
        AND AnimalAliases.Alias LIKE N'%USERINPUT%';

基本上,我希望能够使用多个条件进行内部联接,但其中一个条件与表之一无关,即 LIKE 语句,这是我卡住的地方。

var query = 
    from animal in context.Animals
    join animalAlias in context.AnimalAliases
        on new { animal.AnimalID, "USERINPUT" }
    equals new { animalAlias.AnimalID, animalAlias.Alias }
    select animal;

但这显然不起作用,因为我不想 EQUALS 到 USERINPUT,我想对其执行各种 LIKE 操作..

有人有什么见解吗?

【问题讨论】:

    标签: c# sql linq select inner-join


    【解决方案1】:

    我认为您正在寻找的只是一个普通的 WHERE 子句?

    var query = from animal in context.Animals
       join animalAlias in context.AnimalAliases on animal.AnimalID equals animalAlias.AnimalID
       where animalAlias.Alias.Contains(USERINPUT)
       select animal;
    

    别名文本不是外键关系的一部分 - 所以它不应该在连接中。


    更新 - 在 cmets 之后 - 包括来自 @Steven - 虽然上面的查询是正确的并且确实模仿了原始 SQL - 在输出中使用 Distinct() 可能是明智的 - 这将防止单个动物可能出现多个别名匹配的情况。

    var query = (from animal in context.Animals
       join animalAlias in context.AnimalAliases on animal.AnimalID equals animalAlias.AnimalID
       where animalAlias.Alias.Contains(USERINPUT)
       select animal).Distinct();
    

    【讨论】:

    • 啊,我也写了那个。感谢您的帮助,我确信在大型数据库上,动物别名的搜索速度提高了数百个百分点。在我这样做之前,这很糟糕,并且一直涉及所有动物。
    • 请注意,您的查询可能会返回重复项。您应该调用 .Distinct() 来获取唯一值。
    • @Steven - 好点 - 虽然这实际上也是原始 SQL 所做的事情
    • 哇...你说的完全正确。我不认为这是 OP 所期望的实际行为,但仍然非常尖锐。 + 1 !
    【解决方案2】:

    这样就可以了:

    IQueryable<Animal> query = 
        from animal in context.Animals
        where animal.AnimalAliases
            .Any(a => a.Alias.Contains("USERINPUT"))
        select animal;
    

    或者,您也可以反过来(从AnimalAlias 实体开始,而不是从Animal 实体开始):

    IQueryable<Animal> query = (
        from animalAlias in context.AnimalAliases
        where animalAlias.Alias.Contains("USERINPUT")
        select animalAlias.Animal)
        .Distinct();
    

    【讨论】:

    • 但它必须返回一个 IQueryable 集,所以我认为第一个是答案。实际上我确实想出了另一种方法,不确定它是否对任何人有帮助,或者它是否有效,我还没有检查准确性:
    • IQueryable query = from a in search.Animals join al in search.AnimalAliases on a.AnimalID 等于 al.AnimalID where al.Alias.Contains("USERINPUT") select a;跨度>
    • 请停止在 linq 中使用joins。它们掩盖了您的代码,并且在大多数情况下是不需要的,因为 O/RM 已经知道这些关系。
    • @Philippe:您的查询未返回唯一 Animal 实体的列表。它可以返回重复的Animals。顺便提一句。我的两个查询都返回IQueryable&lt;Animal&gt;。它们在功能上是等效的。
    • @Steven - 我认为在 Linq 中使用 join 是一种很好的做法 - 我同意 Linq2Sql 生成的 SQL 可能具有相同的性能,但是当您移至 Linq2Objects 或其他 ORM 时,您可能会看到性能改进(参见 JS 在 stackoverflow.com/questions/3014123/… 中的回答)——另外,至于 join 是否使代码更加晦涩难懂,我想这取决于个人意见(人们总是会在某些事情上不同意!)
    猜你喜欢
    • 1970-01-01
    • 2018-06-26
    • 1970-01-01
    • 2011-03-03
    • 1970-01-01
    • 1970-01-01
    • 2014-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多