首页 > 解决方案 > Linq 中的三元问题

问题描述

我正在尝试构建一个查询,该查询将允许我添加一个表达式,该表达式将仅返回与某人相关/不相关的联系人。

The base IQueryable looks like this ... 

    internal static IQueryable<OrganizationContact> GetOrganizationContactQuery(IFDBCtx ctx)
    { 
        var query = from rContact in ctx.Contacts.Where(e => e.institution_id.HasValue)

                    join rPerson in ctx.People
                        on rContact.person_id equals rPerson.person_id into peopleGroup
                        from person in peopleGroup.DefaultIfEmpty()

                    select new BLL.OrganizationContact
                    {
                        ID           = rContact.contact_association_id, 
                        Title        = rContact.contact_title,
                        Notes        = rContact.notes,
                        CreatedBy    = rContact.created_by,
                        CreatedDate  = rContact.created_date,
                        UpdatedBy    = rContact.updated_by,
                        UpdatedDate  = rContact.updated_date,
                        ContactName  = (person == null) ? null : person.name,
                        Person       = (person == null) ? null : new BLL.Person { ID = person.person_id, Name = person.name }
                    }

        return query;
    }

但是,这会引发异常...

无法创建类型为“BLL.Person”的空常量值。此上下文仅支持实体类型、枚举类型或原始类型。

当我从 Person 分配中删除 person == null 评估时,异常消失了......

internal static IQueryable<OrganizationContact> GetOrganizationContactQuery(dbContext ctx)
{ 
    var query = from rContact in ctx.Contacts.Where(e => e.institution_id.HasValue)

                join rPerson in ctx.People
                    on rContact.person_id equals rPerson.person_id into peopleGroup
                    from person in peopleGroup.DefaultIfEmpty()

                select new BLL.OrganizationContact
                {
                    ID           = rContact.contact_association_id, 
                    Title        = rContact.contact_title,
                    Notes        = rContact.notes,
                    CreatedBy    = rContact.created_by,
                    CreatedDate  = rContact.created_date,
                    UpdatedBy    = rContact.updated_by,
                    UpdatedDate  = rContact.updated_date,
                    ContactName  = (person == null) ? null : person.name,
                    Person       = new BLL.Person { ID = person.person_id, Name = person.name }
                }

    return query;
}

但现在我还有另一个问题。当我尝试评估是否设置了 Person 时...

var query = GetOrganizationContactQuery(dbContext);
    query = query.Where(e=>Person == null);

我得到另一个例外......

DbIsNullExpression 的参数必须引用原始类型、枚举类型或引用类型。

为了解决这些问题,我尝试评估 ContactName (毕竟它是一种原始类型)。

var query = GetOrganizationContactQuery(dbContext);
    query = query.Where(e=>ContactName == null);

这不会引发异常,而是返回表中的每条记录。事实证明,三元表达式 (person == null) 似乎总是评估为 NULL,即使正确设置了 Person 对象属性的名称!这是此输出的示例。您可以看到 Person 对象已正确设置,但 ContactName 不存在(具有 NULL 值的属性不包含在 JSON 中)。

{
    "ID": 2467,
    "Title": "CEO",
    "CreatedBy": "gstenstrom",
    "CreatedDate": "2019-05-21T17:37:18.997",
    "UpdatedBy": "gstenstrom",
    "UpdatedDate": "2019-05-21T17:37:18.997",
    "Person": {
        "ID": 2610,
        "Name": "John Jones",
    }
}

因此,我无法评估 Person 对象属性,也无法设置 ContactName ...我无法过滤掉与 People 相关联的联系人!

这是一个非常基本的查询,似乎被 Linq 弄得很困难。我错过了什么吗?

经过进一步研究,我发现这有效......

internal static IQueryable<OrganizationContact> GetOrganizationContactQuery(dbContext ctx)
{ 
    var query = from rContact in ctx.Contacts.Where(e => e.institution_id.HasValue)

                join rPerson in ctx.People
                    on rContact.person_id equals rPerson.person_id into peopleGroup
                    from person in peopleGroup.DefaultIfEmpty()

                select new BLL.OrganizationContact
                {
                    ID           = rContact.contact_association_id, 
                    Title        = rContact.contact_title,
                    Notes        = rContact.notes,
                    CreatedBy    = rContact.created_by,
                    CreatedDate  = rContact.created_date,
                    UpdatedBy    = rContact.updated_by,
                    UpdatedDate  = rContact.updated_date,
                    ContactName  = person.name,
                    Person       = new BLL.Person { ID = person.person_id, Name = person.name }
                }

    return query;
}


var query = GetOrganizationContactQuery(dbContext);
    query = query.Where(e=>ContactName != null);

但这并不...

internal static IQueryable<OrganizationContact> GetOrganizationContactQuery(dbContext ctx)
{ 
    var query = from rContact in ctx.Contacts.Where(e => e.institution_id.HasValue)

                join rPerson in ctx.People
                    on rContact.person_id equals rPerson.person_id into peopleGroup
                    from person in peopleGroup.DefaultIfEmpty()

                select new BLL.OrganizationContact
                {
                    ID           = rContact.contact_association_id, 
                    Title        = rContact.contact_title,
                    Notes        = rContact.notes,
                    CreatedBy    = rContact.created_by,
                    CreatedDate  = rContact.created_date,
                    UpdatedBy    = rContact.updated_by,
                    UpdatedDate  = rContact.updated_date,
                    ContactName  = (person.name == null) ? null : person.name,
                    Person       = new BLL.Person { ID = person.person_id, Name = person.name }
                }

    return query;
}

var query = GetOrganizationContactQuery(dbContext);
    query = query.Where(e=>ContactName != null);

我经历了无数的 SO 帖子,但似乎没有人回答我的问题或确定潜在的问题可能是什么。虽然可能是我的无知...

标签: c#.netsql-serverentity-frameworklinq

解决方案


推荐阅读