【问题标题】:NHibernate QueryOver .Left.JoinAlias with additional join criteriaNHibernate QueryOver .Left.JoinAlias 附加连接条件
【发布时间】:2016-03-16 23:40:58
【问题描述】:

我有以下方法:

    public IEnumerable<MyRosterDTO> MyRosterGetCustomers(
        IEnumerable<Guid> SalesRepIds,
        IEnumerable<Guid> escrowOfficerIds,
        IEnumerable<int> targetTypes,
        IEnumerable<int> tagIds,
        IEnumerable<Guid> custTypes,
        IEnumerable<int> distListIds,
        bool myExceptions)
    {
        customerStatusLog cslAlias = null;
        customer custAlias = null;
        customerOptions coAlias = null;
        employee salesRepAlias = null;
        Office officeAlias = null;
        ListTags tagsAlias = null;
        MyRosterDTO dto = null;
        contactInformation contactInfo = null;

        var myRosterQuery = _sms.CurrentSession.QueryOver<customer>(() => custAlias)
                                .JoinAlias(c => c.CustomerOptions, () => coAlias)
                                .Left.JoinAlias(c => c.SalesRep, () => salesRepAlias)
                                .JoinAlias(c => coAlias.Company, () => officeAlias)
                                .Left.JoinAlias(c => c.ContactInfo, () => contactInfo)
                                .Where(x => contactInfo.ContactTypeID == 8);


        #region Where Clauses for parameters
        if (myExceptions)
        {
            myRosterQuery.Where(c => salesRepAlias.Id == _ctx.User.Id && _ctx.User.Id != officeAlias.RepId);
        }
        else
        {
            if (SalesRepIds != null)
            {
                if (SalesRepIds.Contains(Guid.Empty))
                {
                    if (SalesRepIds.Count() > 1) { myRosterQuery.Where(c => salesRepAlias.Id.IsIn(SalesRepIds.ToArray()) || salesRepAlias.Id == null); }
                    else
                    { myRosterQuery.Where(c => salesRepAlias.Id == null); }
                }
                else
                { myRosterQuery.Where(c => salesRepAlias.Id.IsIn(SalesRepIds.ToArray())); }
            }
        }

        if (escrowOfficerIds != null
            && escrowOfficerIds.Any())
        {
            myRosterQuery.Where(c => coAlias.PreferredEscrowOfficer.IsIn(escrowOfficerIds.ToArray()));
        }

        if (targetTypes != null
            && targetTypes.Any())
        {
            myRosterQuery.JoinAlias(c => c.CustomerStatusLog, () => cslAlias)
                         .Where(() => cslAlias.StatusId.IsIn(targetTypes.ToArray()));
        }

        if (tagIds != null
            && tagIds.Any())
        {
            myRosterQuery.JoinAlias(c => c.Tags, () => tagsAlias)
                         .Where(() => tagsAlias.Id.IsIn(tagIds.ToArray()));
        }

        if (custTypes != null
            && custTypes.Any())
        {
            myRosterQuery.Where(c => coAlias.cusTypeID.IsIn(custTypes.ToArray()));
        }

        if (distListIds != null
            && distListIds.Any())
        {
            var distCustIds = _sms.CurrentSession.Query<ListofAgents>()
                              .Where(loa => distListIds.Contains(loa.ListId))
                              .Select(loa => loa.AgentId)
                              .Distinct();

            myRosterQuery.Where(c => c.Id.IsIn(distCustIds.ToArray()));
        }
        #endregion

        return myRosterQuery.SelectList(list => list
            .SelectGroup(c => c.Id).WithAlias(() => dto.Id)
            .SelectGroup(c => c.FirstName).WithAlias(() => dto.FirstName)
            .SelectGroup(c => c.LastName).WithAlias(() => dto.LastName)
            .SelectGroup(() => officeAlias.Name).WithAlias(() => dto.CompanyName)
            .SelectGroup(() => officeAlias.Address1).WithAlias(() => dto.Address1)
            .SelectGroup(() => officeAlias.Address2).WithAlias(() => dto.Address2)
            .SelectGroup(() => officeAlias.City).WithAlias(() => dto.City)
            .SelectGroup(() => officeAlias.State).WithAlias(() => dto.State)
            .SelectGroup(() => officeAlias.Zip).WithAlias(() => dto.Zip)
            .SelectGroup(() => contactInfo.ContactData).WithAlias(() => dto.Phone)
            .SelectGroup(() => salesRepAlias.FirstName).WithAlias(() => dto.SalesRepFirstName)
            .SelectGroup(() => salesRepAlias.LastName).WithAlias(() => dto.SalesRepLastName)
            )
            .TransformUsing(Transformers.AliasToBean<MyRosterDTO>())
            .List<MyRosterDTO>();
    }

查询既好又快,但是如果记录没有 ContactTypeID 为 8 的contactInfo,则会出现问题,那么该记录就会从最终结果中剔除。 (8 等于电话号码,仅供参考。)

我需要做的是获取客户记录,显示所有客户,但在可用的情况下提供电话号码,在不提供的情况下什么也不提供。

诀窍在于,contactInfo 包含多种类型的联系信息(电子邮件、电话、传真等),并且没有上面的 .Where 子句,输出数据会爆炸,在屏幕上显示用户的每个 contactInfo 记录的记录有 - 因此数据库中具有 3 个 contactInfo 类型的用户显示为 3 行输出数据。

此方法用于根据输入参数获取客户列表,但不会显示没有电话号码的客户,以及有电话号码的客户,我只显示有电话号码的客户。

如果这是 SQL,我就会有一个很好的

LEFT JOIN ContactInfo as CI on customer.UserId = CI.UserId AND CI.ContactTypeID = 8

我的查询结果会显示有和没有电话号码的客户。

【问题讨论】:

    标签: c# nhibernate left-join queryover


    【解决方案1】:

    您需要“with 子句”,它来自 HQL,并已集成在查询中:

    .Left.JoinAlias(c => c.ContactInfo, () => contactInfo, () => contactInfo.ContactTypeID == 8)
    

    这会产生以下 SQL:

    SELECT ...
    FROM 
       ...
      LEFT OUTER JOIN ContactInfo as CI on (customer.UserId = CI.UserId 
        AND CI.ContactTypeID = 8)
    

    对比

    .Left.JoinAlias(c => c.ContactInfo, () => contactInfo)
    .Where(x => contactInfo.ContactTypeID == 8)
    

    创造了

    SELECT ...
    FROM 
       ...
       LEFT OUTER JOIN ContactInfo as CI on (customer.UserId = CI.UserId)
    WHERE CI.ContactTypeID = 8
    

    HQL 中的 WITH 子句如下所示:

    FROM 
      ...
      left join ContactInfo ci WITH ci.ContactTypeID = 8
    

    看到这个blog post by Fabio

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多