【问题标题】:Linq error: The cast to value type 'Int32' failed because the materialized value is nullLinq 错误:转换为值类型“Int32”失败,因为具体化值为 null
【发布时间】:2013-11-05 06:50:31
【问题描述】:

...但它不为空。

仅供参考 - 此错误存在许多线程,但我没有看到使用匿名类型。

我在 Linq 查询中遇到奇怪的 InvalidOperationException。

消息:“转换为值类型 'Int32' 失败,因为具体化值为 null。结果类型的泛型参数或查询必须使用可为空的类型。”

令人困惑的是,它在创建匿名类型时出错:

var workstepid = 484,449;

var wsData = ion.xWorkSteps
   .Where(w => w.WorkStepId == workstepId)
   .Select(w => new
   {
       w.WorkStepId,
       w.ServiceId,
       w.Service.TitleId,
       w.Service.Title.OrderId,
       w.Service.Title.AltTitleId
   }).SingleOrDefault();

在 LinqPad 中,这个特定的查询运行良好,并且使用的 workstepId 为匿名类型的每个属性返回一个整数值。那么,当任何属性都没有空值时,为什么会出现转换错误!?

仅供参考,最后一个属性 AltTitleId 是可为空的 int,其他属性是 int。 另外,这段代码是几周前写的,直到今天我才收到这个错误。我的 EF 有什么时髦的东西吗?

编辑:已解决

我们在数据库中使用软删除,将删除的记录设置为 Acive=0。 事实证明,在 edmx 表上的 EF 中设置了一个属性,用于过滤掉非活动记录(针对 Active=1 的过滤器)。自然,这不会影响 Linqpad,它给了我预期的结果,但由于这是我正在测试的旧记录,标题记录 (Service.Title) 已标记为 Active=0,因此返回 null。

感谢大家的帮助。

【问题讨论】:

  • w.workstepid 表中是否有空值?或者这是模型中可以为空的类型?
  • 这不能在 linqpad 中运行。第一行是非法语法。
  • LinqPad 运行 C# 5.0 - 也许它是语言中的东西
  • Good discussion 在这里。
  • 你在延迟加载Service 类吗?你能告诉我们你的WorkStep 班级吗?

标签: c# .net linq entity-framework c#-4.0


【解决方案1】:
var workstepid = 484,449;

var wsData = ion.xWorkSteps
   .Where(w => w.WorkStepId == workstepId)
   .Select(w => new
   {
      w.WorkStepId.Value,
      w.ServiceId.Value,
      w.Service.TitleId.Value,
      w.Service.Title.OrderId.Value,
      w.Service.Title.AltTitleId.Value
   }).SingleOrDefault();

您好,您需要在 int 数据类型中添加 .Value 以接受空值。希望这会有所帮助

【讨论】:

  • 能够为 AltTitleId 添加“.Value”,但不能为另一个添加(AltTitleId 是唯一可以为空的 FYI)。新的编译错误:错误 231 'AnonymousType#1' 不包含 'AltTitleId' 的定义,并且找不到接受类型为 'AnonymousType#1' 的第一个参数的扩展方法 'AltTitleId'(您是否缺少 using 指令或程序集参考?)
【解决方案2】:

如果w.WorkStepId 可以为空,请尝试将您的变量设置为...

int? workstepid = 484449;

【讨论】:

  • 你能显示你使用wsdata的代码吗,这可能是错误所在。
【解决方案3】:

我想,问题出在您的 SingleOrDefault() 中。

我想你得到 0 条记录:

var workstepid = 484,449;

var len = ion.xWorkSteps
   .Where(w => w.WorkStepId == workstepId)
   .Length();

然后必须将匿名类型替换为默认值(这就是 SingleOrDefault 所做的),但是您的匿名类型没有默认值。

尝试将其更改为:

    var wsData = ion.xWorkSteps
   .Where(w => w.WorkStepId == workstepId)
   .Select(w => new
   {
       w.WorkStepId,
       w.ServiceId,
       w.Service.TitleId,
       w.Service.Title.OrderId,
       w.Service.Title.AltTitleId
   })
   .Take(1)
   .ToArray();

【讨论】:

    【解决方案4】:

    可能某处没有 Service/Title/Order id,但如果它声明为 int 匿名类型期望 int(不可为空),但从数据库返回 null。 尝试改写为:

    var workstepid = 484,449;
    
    var wsData = ion.xWorkSteps
       .Where(w => w.WorkStepId == workstepId)
       .Select(w => new
       {
         WorkStepId = (int?)w.WorkStepId,
         ServiceId = (int?)w.ServiceId,
         TitleId = (int?)w.Service.TitleId,
         OrderId = (int?)w.Service.Title.OrderId,
         w.Service.Title.AltTitleId
       }).SingleOrDefault();
    

    【讨论】:

      猜你喜欢
      • 2013-06-18
      • 1970-01-01
      • 2013-03-18
      • 2016-08-02
      • 1970-01-01
      • 1970-01-01
      • 2013-02-24
      相关资源
      最近更新 更多