我在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
答案 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)