在我支持的应用程序中,由于客户端尚未提交数据,有时关联可能为空。除了做一个空检查,我不知道还有什么其他方法可以处理这个问题。数据库是一成不变的(其他应用程序也使用它)它把我的代码弄得一团糟。我想知道是否有更好的方法可以做到这一点(这段代码是匿名类型的,但使用类没有什么区别。我不能添加检查null的谓词,因为如果账单存在,无论索赔患者或索赔是否还不存在,都需要返回信息。以下是简化版本:
var baseQuery = Context.Bills.AsNoTracking()
.Select
(
bill => new
{
bill.BillId,
bill.BillStatus,
patientId = bill.ClaimPatient != null ? bill.ClaimPatientId : null,
claimPatientId = bill.ClaimPatient != null && bill.ClaimPatient.Claim != null ? bill.ClaimPatientId : null,
bill.UserNumber,
}
);
这种空检查可以一直持续下去。我知道可能有更好的方法,当我看到它时,我会面对植物,因为它可能是我错过的简单而明显的东西。
我发现像下面这样的扩展方法有时对处理这个问题很有用。
public static class Extensions
{
public static U Maybe<T, U>(this T t, Func<U> f) where U : class
{
return t != null ? f() : null;
}
public static U Maybe<T, U>(this T t, Func<T, U> f) where U : class
{
return t != null ? f(t) : null;
}
public static U? MaybeNullable<T, U>(this T t, Func<U> f) where U : struct
{
return t != null ? f() : (U?)null;
}
public static U? MaybeNullable<T, U>(this T t, Func<T, U> f) where U : struct
{
return t != null ? f(t) : (U?)null;
}
}
下面是一些用法示例。
bill.ClaimPatient.Maybe(() => bill.ClaimPatientId)
bill.ClaimPatient.Maybe(cp => cp.Id)
person.Maybe(p => p.Employer).Maybe(e => e.Address)
好消息:SQL没有这个null
引用概念。因此,您可以将检查(在本例中)简化为对int?
的简单强制转换。
var baseQuery = Context.Bills.AsNoTracking()
.Select
(
bill => new
{
bill.BillId,
bill.BillStatus,
patientId = (int?)bill.ClaimPatientId,
claimPatientId = (int?)bill.ClaimPatientId,
ClaimPatient.UserNumber,
}
);
整个语句被翻译成SQL。CLR首先知道的是来自数据库的结果集。此集合可能包含null值,因此您只需确保最终结果可以在一个属性中包含int
和null
。
也许对于第二个Id值,您需要bill.ClaimPatient.Claim != null ? bill.ClaimPatientId : null
,但我认为这是业务逻辑,而不是空安全检查。