【问题标题】:C# Linq join table, where left table might be nullC# Linq 连接表,其中左表可能为空
【发布时间】:2014-08-08 09:29:29
【问题描述】:

请看我下面的例子。在这里,为了这个问题,我有 3 个表 - ma​​inTabletableAtableB。在表中,PK 字段表示主键,FK 字段表示外部字段。

我无法加入 3 张桌子。在 mainTable 中,有引用 tableA 的字段“nullableFK”。它可能为空。因此,要加入 tableA,我使用 DefaultIfEmpty() 使用 Left Join。问题开始了,当我需要在表 A 和表 B 中匹配的字段上加入第三个表时。下面的示例抛出,InvalidOperationException 带有以下消息:

"The cast to value type 'System.Boolean' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type."

我尝试在没有 DefaultIfEmpty 的情况下加入 tableB - 据我所知,这将是内部联接。但是,Sequence 不包含任何元素。

目标是 -

返回 ma​​inTabletableAtableB 的值。

如果在ma​​inTable中,nullableFK为null,返回ma​​inTabletableAtableB的值为null,

            var query = (from mainTable in db.mainTables
                        where mainTable.PK == id

                        join tableA_ in db.tablesA on mainTable.nullableFK equals tableA_.FK into A
                        from tableA in A.DefaultIfEmpty()

                        join tableB_ in db.tablesB on tableA.PK equals tableB_.PK into B
                        from tableB in B.DefaultIfEmpty()

                        select new {
                            val1 = mainTable.fieldA,
                            val2 = tableA.fieldB,
                            val3 = tableB.fieldC
                        }).First();

答案 - 检查select new {} 中的null 值。

【问题讨论】:

  • 请明确你的目标..
  • 如果您已经设置了参照完整性,那么您应该有一个实体模型,该模型将这些外键作为从主表到“a”和“b”的集合。停止使用 linq 中的“加入”表达式使事情变得复杂,只需去获取“选择新 {”部分中的值,然后在必要时检查和默认空值。
  • 请在select new { //...中显示代码
  • 在select new {}中,有来自mainTabletableAtableB的所有数据。但问题不存在。即使我根本没有从这些表中选择任何内容,查询也不起作用,因为连接不起作用.. 编辑:我可能错了。我想我应该检查 select new {} 中的空值

标签: c# sql sql-server database linq


【解决方案1】:

看起来 OP 在对问题的编辑中指定了答案,但不清楚如何实施。他说要在 select new {} 中检查 null。

我能够通过将值转换为可空类型来完成这项工作。在下面的示例中,我假设 tableA.fieldB 和 tableB.fieldC 都是 int 类型:

 var query = (from mainTable in db.mainTables
              where mainTable.PK == id

              join tableA_ in db.tablesA on mainTable.nullableFK equals tableA_.FK into A
              from tableA in A.DefaultIfEmpty()

              join tableB_ in db.tablesB on tableA.PK equals tableB_.PK into B
              from tableB in B.DefaultIfEmpty()

              select new {
                  val1 = mainTable.fieldA,
                  val2 = (int?)tableA.fieldB,
                  val3 = (int?)tableB.fieldC
              }).First();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-30
    • 1970-01-01
    • 2017-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多