【问题标题】:Convert SQL (Left Outer Join's) to LINQ将 SQL(左外连接)转换为 LINQ
【发布时间】:2016-12-19 05:52:26
【问题描述】:

我在将具有多个 LEFT OUTER JOIN 的 Oracle Sql 查询转换为 LINQ 时遇到问题。我的尝试没有返回预期的结果。有人可以帮助将下面的 SQL 查询转换为 LINQ。

string currentCulture = Culture.GetCulture();
string query = @"SELECT *
               FROM CTGLBL g, CTTGLBL ct, CTLANG lang
               WHERE g.sysctglbl = ct.sysctglbl(+) AND 
                     ct.sysctlang = lang.sysctlang (+) AND
                     NVL(lang.activeflag, 1)= 1 AND
                     (ISOCODE LIKE '" + currentCulture + "%' OR ISOCODE IS NULL)";

ISOCODE 属于 CTLANG 表。

ps。我不能使用 LINQPAD 或 Linqer 之类的工具。

【问题讨论】:

  • ISOCODE属于什么表?
  • 属于CTLANG
  • (+) 是什么,这也不是真正的右连接....这是通过 where 子句完成的正常连接..
  • 如果我是正确的,这是右外连接的旧语法:techonthenet.com/oracle/joins.php 转到右外连接并检查旧语法
  • 啊好吧 - 不知道那个语法

标签: c# sql oracle linq


【解决方案1】:

但是对于您的 sql(并在此处转换为 linq)的更好做法是使用 join 而不是 where 来连接表:

string currentCulture = Culture.GetCulture();

var result = from g in CTGLBL
             join ct in CTTGLBL on g.sysctglbl equals ct.sysctglbl into ctj
             from ct in ctj.DefaultIfEmpty()
             join lang in CTLANG on ct.sysctlang equals lang.sysctlang into langj
             from lang in langj.DefaultIfEmpty()
             where (lang == null ?  1 : (lang.activeflag ?? 1)) == 1 &&
                 (lang?.ISOCODE.StartsWith(currentCulture) || lang?.ISOCODE == null)
             select new { g, ct, lang };

您还可以为您的CTLANG 设置一个"nested select",如下所示:

string currentCulture = Culture.GetCulture();

var result = from g in CTGLBL
             join ct in CTTGLBL on g.sysctglbl equals ct.sysctglbl into ctj
             from ct in ctj.DefaultIfEmpty()
             join lang in CTTGLBL.Where(lang => lang.activeflag ?? 1 == 1 &&
                                                  (lang.ISOCODE.Contains(currentCulture) ||
                                                   lang.ISOCODE == null))
             on ct.sysctlang equals lang.sysctlang into langj
             from lang in langj.DefaultIfEmpty()
             select new { g, ct, lang };

【讨论】:

  • 谢谢,马上试试。 ISOCODE 属于表 CTLANG。
  • 感谢我在聊天中添加了一些我的桌子的图片。希望它能让它更清楚一点。
  • @Devid - 它对你有用吗?我在第一个使用 lang == null 的查询中遇到了一个错误 - 现在已修复
  • 它工作得很好 :) lang?.ISOCODE 只有一个问题(编译器错误是它不能将 bool? 应用于 bool)。我做了擦除?一切正常。稍后我会接受你的回答。非常感谢。
【解决方案2】:

(我看到的是左连接,而不是右连接)

假设您的架构中的表之间有正确的关系,使用 SQL 服务器(Linq TO SQL)这将起作用,不确定它是否支持 Oracle:

string currentCulture = Culture.GetCulture();

var data = from g in db.CTGLBL
           from ct in g.CTTGLBL.DefaultIfEmpty()
           from lang in g.CTLANG.DefaultIfEmpty()
           where !g.CTLANG.Any() || 
                 ( lang.activeflag == 1 &&
                   lang.ISOCODE.StartsWith(currentCulture))
           select new {g, ct, lang};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-25
    • 1970-01-01
    • 2015-09-30
    • 2021-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多