C# 具有1:0..n关系的实体框架和关系,当它为0时该怎么办?

C# 具有1:0..n关系的实体框架和关系,当它为0时该怎么办?,c#,null,navigation,associations,entity-framework-4.1,C#,Null,Navigation,Associations,Entity Framework 4.1,在我支持的应用程序中,有时关联可以为null,因为客户端尚未提交数据。除了执行空检查之外,我不知道还有什么其他方法来处理这个问题。数据库是一成不变的(其他应用程序也会使用它),它会把我的代码弄得一团糟。我想知道是否有更好的方法来执行此操作(此代码将成为匿名类型,但使用类没有任何区别。我不能添加检查null的谓词,因为如果账单存在,则无论索赔患者或索赔是否还不存在,都需要返回信息。以下是一个简化版本: var baseQuery = Context.Bills.AsNoTr

在我支持的应用程序中,有时关联可以为null,因为客户端尚未提交数据。除了执行空检查之外,我不知道还有什么其他方法来处理这个问题。数据库是一成不变的(其他应用程序也会使用它),它会把我的代码弄得一团糟。我想知道是否有更好的方法来执行此操作(此代码将成为匿名类型,但使用类没有任何区别。我不能添加检查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,
                }
            );

这种空值检查可以继续进行下去。我知道可能有更好的方法,当我看到它时,我会面对plant,因为它可能是我错过的非常简单和明显的东西。

我发现像下面这样的扩展方法有时对处理此问题很有用

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;
    }
}

好消息: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首先知道的是来自数据库的结果集。该结果集可能包含空值,因此您只需确保最终结果可以在一个属性中包含
int
null


也许对于第二个ID值,你需要<代码> Bel.CuraPurth.Realth.Nul.Bel.CalApHealthTime:NULUT/CONDE>,但是我认为业务逻辑,而不是NULL安全检查。

这肯定是非常干净的。我真的很喜欢它。我会把这个问题打开几分钟,看看是否有其他人想添加一些有趣的东西,但是它看起来很有意思。就像你会得到我的投票一样。谢谢,我想知道我是否需要匿名类中匿名类型的演员阵容,尽管一旦我完成查询,我将为这些字段制作一个POCO。这将真正清理我的代码中的所有内容。哦,是的,实现命名类将同样简单。感谢Gert和Timothy。
var baseQuery = Context.Bills.AsNoTracking()
.Select
(
    bill => new
    {
        bill.BillId,
        bill.BillStatus,
        patientId = (int?)bill.ClaimPatientId,
        claimPatientId = (int?)bill.ClaimPatientId,
        ClaimPatient.UserNumber,
    }
);