【问题标题】:Left outer join , Object reference not set to an instance of an object左外连接,对象引用未设置为对象的实例
【发布时间】:2012-08-24 19:16:22
【问题描述】:

我正在尝试对 2 个对象执行左外连接并收到错误:对象引用未设置为对象的实例。

物体看起来像那样

  var deliverables = OCHART.GetACAPValues(organization, ReportingPeriod, FiscalYear, "(09-10.10a) Outreach Significant").ToList();
  var references = (from rf in OCHART.References where rf.RefType.Equals("09-10.10a") && rf.Comments.Equals("2") select rf).ToList();

其中可交付成果可能经常返回 0 条记录。不幸的是,我不能只是去连接数据库中的两个表,因此可交付成果必须是一个对象。

有人可以指点我正确的方向

谢谢,

我的代码是

 var items = (from rf in references
              join pt in deliverables on rf.Description equals pt.b into prt
              from x in prt.Where(prt2 => prt2.a.Equals(audience)).DefaultIfEmpty()
              where rf.RefType.Equals("09-10.10a") && rf.Comments.Equals("2")
              select new 
              {
                    audience = (string)(audience == null ? "" : audience),
                    RefType = (string)(rf.RefType == null ? "" : rf.RefType),
                    RefOrder = (int)(rf.RefOrder == null ? 0 : rf.RefOrder),
                    refName = (string)(rf.Description == null ? "" : rf.Description),
                    collumn_attr = (string)(x.b == null ? string.Empty : x.b),
                    value = (int)(x.ACAP == null ? (int?)null : x.ACAP)
               })
               .OrderBy(o => o.RefOrder)
               .Take(9)
               .ToList();

编辑: 经过更多调试后,我的代码中的以下几行似乎出现错误

collumn_attr = (string)(x.b == null ? string.Empty : x.b),
value = (int)(x.ACAP == null ? (int?)null : x.ACAP)

我注意到,即使我在可交付成果中有值(添加用于测试),并且当值匹配时,查询将正确执行,但是当可交付成果中没有匹配时,我就会收到错误消息。

问题可能在于处理空值。

【问题讨论】:

    标签: c# linq-to-sql c#-3.0 linq-to-objects


    【解决方案1】:

    我认为x 为空,并在以下几行中导致NullReferenceException:

    collumn_attr = (string)(x.b == null ? string.Empty : x.b),
    value = (int)(x.ACAP == null ? (int?)null : x.ACAP)
    

    此判断基于from x in 行的DefaultIfEmpty() 调用,典型的left-outer-joins。

    在数据库代码中,您可以编写类似x.ACAP == null 的内容来检测没有匹配连接元素的情况。如果您更改此设置,将“x.property == null”检查替换为“x == null”检查,我怀疑您的问题会解决。

    第二行仍然存在问题 - 如果您尝试将值 (int?)null 强制转换为整数,您将在运行时遇到异常。使用有意义的默认 int 值,例如 0,以防 x == null 将其清除。

    【讨论】:

    • 我尝试了您的建议,您发现了,我做了 value = (int)(x == null ? 0 : x.ACAP) 并且现在一切正常。非常感谢您的帮助。谢谢。
    【解决方案2】:

    如果您单步执行您的代码,在执行查询之前,您是否真的看到“可交付成果”和“参考”中填充了数据?

    调查您在查询中使用的所有子表/属性。您收到该错误的原因很可能是因为您在比较时使用的属性之一为空。 .RefType .Comment 例如。 也许 .RefType 为 null 并且在最后排序时遇到问题。很难说没有看到这两个集合中的内容。

    在您的评论后添加:

    请注意,当您的变量可能为空时,最好不要使用 .Equals()。使用 == 代替。参考:http://www.dotnetperls.com/string-equals

    还可以想象(x.ACAP == null ? (int?)null : x.ACAP) 返回一个null。 您将整个内容转换为 int :value = (int)(x.ACAP == null ? (int?)null : x.ACAP)。将 null 转换为 n int 显然会失败

    【讨论】:

    • 引用总是被填充,但可交付成果列表有可能为 0 并且为空而没有任何记录,当我调试代码时,我得到的错误是 collumn_attr = (string)(xb = = null ? string.Empty : xb) 行,在线值 = (int)(x.ACAP == null ? (int?)null : x.ACAP)
    • 我注意到,即使我在可交付成果中有值(添加用于测试)并且值匹配时查询将正确执行,但是当没有匹配时,我会收到错误消息。问题可能在于处理空值。
    【解决方案3】:

    为了记录,C# 6.0 中新的 Null 条件运算符可以这样使用:

                    collumn_attr = x?.b ?? string.Empty,
                    value = x?.ACAP
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-13
      相关资源
      最近更新 更多