【问题标题】:LINQ to SQL lambda where [nullable object must have a value error]LINQ to SQL lambda where [nullable object must have a value error]
【发布时间】:2011-08-22 17:53:43
【问题描述】:

我收到了错误

[可为空的对象必须有值]

它指向代码的以下部分

.Min(x => x.Time)

这是整个函数。

public DateTime GetFirstRecord(long userId)
        {
            DateTime firstRecordDate;

            using (DeviceExerciseDataDataContext context = new DeviceExerciseDataDataContext())
            {
                firstRecordDate = (DateTime)context.Datas.Where(x => x.UserID.Equals(userId)).Min(x => x.Time);
            }

            return firstRecordDate;
        }

另外,我如何调试这个函数 lambda?当我将鼠标悬停在 x 上时,它没有显示任何价值。当我尝试在即时窗口中打印时,它说“名称'x'在当前上下文中不存在”

编辑:

So I've updated my code to this:

public DateTime? GetFirstRecord(long userId)
        {
            DateTime? firstRecordDate;
            firstRecordDate = DateTime.Now;

            using (DeviceExerciseDataDataContext context = new DeviceExerciseDataDataContext())
            {
                var test = context.Datas.Where(x => x.UserID.Equals(userId));
                if (test != null)
                    firstRecordDate = (DateTime)test.Min(x => x.Time);
                else
                    firstRecordDate = null;   
            }

            return firstRecordDate;
        }

但我仍然收到保存错误。

在数据库中,任何地方都没有空值。哦,它不会转到 if/else 块中的 else。

【问题讨论】:

  • 要调试 lambda,您可以在 lambda 本身上放置一个断点,为此将光标放在 lambda 内并按 [F9],断点将位于 lambda 中而不是整行.
  • 测试test != null 是没有意义的,因为test 将只是从Where() 子句返回的迭代器,而且肯定不会是null。能给我们看看模型吗? x.TimeDateTime 还是 Nullable<DateTime>test.Count() 的值是多少?
  • @James Michael Hare:不能使用 Linq2SQL,除非你强制它先列出。
  • 关于 Linq2SQL 的好消息

标签: c# .net linq-to-sql lambda


【解决方案1】:

很有可能 context.Datas 可能为 null 或 Data 的任何 userId 可能为 null 或 x.Time 为 null 并且您尝试将其转换为 (DateTime) 而不是 (DateTime?)。

您必须添加条件以在赋值语句中捕获这些空值,例如:

DateTime? datevalue = context.Datas == null
    ? null
    : (DateTime?)context.Datas.Where(x => x.UserId != null && x.UserID.Equals(userId))
                              .Min(x => x.Time);

【讨论】:

  • 不错的收获!我忘记了 DateTime 的铸造也需要问号。感谢大家!为所有人+1!哈哈。因为我几乎使用了每个人的想法。
【解决方案2】:

如果 firstRecordDate 可能为 null,则不允许使用 .Min。

你可以试试这个吗?

firstRecordDate = (DateTime)context.Datas.Where(x => x.UserID.Equals(userId));
if (firstRecordDate.Count() > 0) firstRecordDate = firstRecordDate.Min(x => x.Time); 

如果可行,那就是你的问题。可能有更优雅的方法来处理这个问题,但至少你会有一个解决方法。

【讨论】:

  • 好的,我已经尝试过您发布的内容,但仍然遇到同样的错误。请参阅上面,因为我已经发布了我新更新的代码。
【解决方案3】:

如果您可以确定至少有一行有有效时间,您可以过滤掉以null为时间的条目(或处理返回DateTime.MaxValue的情况)

firstRecordDate = context.Datas.Where(x => x.UserID == userId)
                               .Select( x=> x.Time ?? DateTime.MaxValue)
                               .Min();

【讨论】:

  • 我的表中没有任何空值。这就是为什么这有点让我发疯,哈哈。
  • @Fritos:Time 是否指定为允许空值?这可能是问题所在。
【解决方案4】:

试试

(DateTime)context.Datas.Where(x => x.UserId != null && x.UserID.Equals(userId)).Min(x => x.Time)

userID != null 应该首先评估,这将在您到达 Min 时防止出现空值。我还没有测试过,但我想我记得过去做过类似的事情。

【讨论】:

  • 这只会阻止nulls 用于x.UserId,而不是x.Time
  • 对不起,我想我看错了。无论哪种方式,如果您将 != null 条件放在 where 子句的开头,它应该可以解决问题。
【解决方案5】:

Min 函数正在尝试返回最小值,我之前遇到过此消息,当时 IQueryable 没有返回任何元素 - 您需要在调用之前检查元素是否存在,或声明firstRecordDate 作为DateTime?

监视窗口不支持调试 lambda。如果您想调试它,我建议改为将其设置为多行的长格式 lambda 以便调试

.Where(x =>
   {
       return x.ToString();
   });

您将能够调试内部方法代码。

【讨论】:

  • 所以我已经将 firstRecordDate 设置为 DateTime?,并且我正在检查是否返回了任何记录(嗯,我想我是,检查 null 是否有效?[请参阅代码以上]),但我仍然遇到同样的问题。
  • 您仍在尝试将 null 转换为 DateTime。 AKA (DateTime)test.Min(x => x.Time); 应该是 (DateTime?)test.Min(x => x.Time); 如果有的话。此外,您不应该调用test != null,但test.Any() test 永远不会为空,它总是会是某种编译器生成的enumerable 调用。
【解决方案6】:

如果 context.Datas.Where(x => x.UserID.Equals(userId)) 不返回任何值,您将收到该错误。

如果你使用日期时间?而不是 DateTime,它将通过返回 null 来避免此错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-08
    • 1970-01-01
    • 2016-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多