【问题标题】:LINQ - join with OR conditionLINQ - 加入 OR 条件
【发布时间】:2017-08-20 09:34:39
【问题描述】:

我有两个实体,用户和友谊,它们看起来像:

    public class User
    {
        public int UserId { get; set; }
        (...)
    }

    public class Friendship
    {
         public int SenderId { get; set; }
         public int ReceiverId { get; set; }
         (...)
    }

我想创建一个简单的查询,在 SQL 中如下所示:

    SELECT * FROM Users as U
    INNER JOIN Friendships as F ON U.UserId = F.ReceiverId OR U.UserId = F.SenderId
    Where U.Nick != VARIABLE

换句话说,我想选择用户的所有朋友。

而我无法做到这一点。我找到了一个解决方案,其中一个使用联合创建两个单独的连接查询并且它可以工作 - 但为数据库创建这样的查询效率不高。

【问题讨论】:

    标签: linq entity-framework


    【解决方案1】:

    LINQ 中的连接总是等值连接。基本上你需要多个from 子句和一个where 子句:

    var query = from u in db.Users
                where u.Nick != variable
                from f in db.Friendships
                where u.UserId == f.ReceiveId || u.UserId == f.SenderId
                select ...;
    

    现在在 LINQ to Objects 中可能有更有效的方法来执行此操作 - 但我希望基于 SQL 的 LINQ 提供程序能够生成具有足够好执行计划的查询。它实际上可能不会在 SQL 中创建 JOIN,但我希望它与您显示的连接具有相同的执行计划。

    【讨论】:

    • 我使用的是 Entity Framework Core,这会导致交叉连接而不是内部连接
    • @jonmeyer:但是交叉连接仍然给出与等效内部连接相同的结果?这不会让我感到惊讶 - 正如我在答案中所说的那样。
    【解决方案2】:

    简单写:

    from U in db.Users
    from F in Friendships.Where(x => U.UserId == F.ReceiverId || U.UserId == F.SenderId)
    where U.Nick != VARIABLE
    select new {u, f};
    

    【讨论】:

    • @JoeTuskan 它会进行内部连接。 (检查查询计划)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-30
    • 1970-01-01
    相关资源
    最近更新 更多