linq to sql Object引用未设置为对象

时间:2013-06-06 17:22:32

标签: c# linq linq-to-sql

我在Linq to Sql中有这个查询

decimal Rewards = db.User.FirstOrDefault(x => x.FFUserID == UserID).TotalCommission;

此查询未找到与userID匹配的记录,因此很明显这就是抛出异常的原因。我的问题是 - 我认为通过使用.FirstOrDefault()如果没有记录它将返回默认对象 - 也认为此默认对象的0.0M默认值为TotalCommission。如果这不是它的工作原理那么这将是写这个的最佳方式,希望它被设置为默认的0.0M

这是最好的吗?

decimal Rewards = db.User.FirstOrDefault(x => x.FFUserID == UserID)
                         .TotalCommission ?? 0.0M

2 个答案:

答案 0 :(得分:7)

如果找不到任何项,

FirstOrDefault将返回null。因此,当您访问TotalCommission属性时,可能会有NullReferenceException。我想你想这样做:

decimal Rewards = db.User.Where(x => x.FFUserID == UserID)
                         .Select(x => x.TotalCommission)
                         .FirstOrDefault();

或者在查询语法中:

decimal Rewards =
    (from x in db.User
     where x.FFUserID == UserID
     select x.TotalCommission)
    .FirstOrDefault();

更新:从C#6.0开始,您现在可以使用null-conditional operators执行与您最初预期非常相似的操作:

decimal Rewards = db.User.FirstOrDefault(x => x.FFUserID == UserID)
                        ?.TotalCommission ?? 0.0M

这里的?.将安全地处理在数据库中找不到给定用户ID并返回(decimal?)null的情况。普通的旧null-coalescing operator?? 0.0M将为您提供您期望的默认值。

答案 1 :(得分:3)

decimal Rewards = db.User.FirstOrDefault(x => x.FFUserID == UserID)
                         .TotalCommission ?? 0.0M

在这种情况下,您确定TotalCommission将返回值。但是FirstOrDefault()返回的对象怎么样呢?你必须先关心它然后再做其余的事情。

当你使用 firstOrDefault 时,结果可能为null。所以我们必须在访问typed对象的任何属性之前检查nullable。否则你会得到 NulllRefranceExcelption

因此您必须小心检查空引用

或者你也可以这样做。

var result = db.User.FirstOrDefault(x => x.FFUserID == UserID);


if(result !=null)
{
 var mydata = result.TotalCommission;
}

这里是 FirstOrDefault 扩展方法

的实现
     public static TSource FirstOrDefault</tsource,><tsource>(this IEnumerable</tsource><tsource> source) {
         ........
.........
                return default(TSource);
            }

所以在这里你可以看到结果是默认的(TSource),这意味着如果TSource是refrance类型,这将返回null,或者如果TSource是值类型,那么这将返回默认值TSource。这里是Default关键字的一些示例实现。

 Console.WriteLine(default(Int32)); // Prints "0"
        Console.WriteLine(default(Boolean)); // Prints "False"
        Console.WriteLine(default(String)); // Prints nothing (because it is null)