NHibernate QueryOver,其中ID在列表中

时间:2014-08-12 15:07:23

标签: asp.net-mvc nhibernate queryover

我有一个网页,其中包含可过滤数据的条件字段。对此的查询是:

        CompanyAddress ca = null;
        CompanyAddress cad = null;
        WorkInfo wi = null;
        PrivateInfo pi = null;
        SearchResultInfo sri = null;

        /***************************/
        /* SEARCH FOR MAIN COMPANY */
        /***************************/

        var company = Session.QueryOver<Company>()
            .JoinAlias(c => c.Addresses, () => ca)
            .Where(() => ca.Main)
            .Where(c => c.Status == ContactStatus.Approved)
            .Select(
                Projections.Property("Id").WithAlias(() => sri.TopId),
                Projections.Property("ca.Id").WithAlias(() => sri.Id),
                Projections.Property("Name").WithAlias(() => sri.Name),
                Projections.Property("ca.Address").WithAlias(() => sri.Address),
                Projections.Property("ca.ContactData").WithAlias(() => sri.ContactData),
                Projections.Constant(ContactClassType.Company).WithAlias(() => sri.Type)
            );

        if (!string.IsNullOrEmpty(_name)) company = company.WhereRestrictionOn(c => c.Name).IsLike("%" + _name + "%");

        //// TODO: fix error    
        if (_selectedTag != null) company = company.Where(Restrictions.In("_selectedTag", ca.Tags.Select(x => x.Tag.Id).ToArray()));

        if (!string.IsNullOrEmpty(_selectedCity)) company = company.Where(() => ca.Address.City == _selectedCity);          

        if (_selectedCountry != null) company = company.Where(() => ca.Address.Country.Id == _selectedCountry);

        if (!string.IsNullOrEmpty(_selectedZipCode)) company = company.Where(() => ca.Address.ZipCode == _selectedZipCode);          

        company.TransformUsing(Transformers.AliasToBean<SearchResultInfo>());

现在,如果selectedTag有一个ID,那么查询会给我一个错误,告诉ca为null。所有其他where子句除了这个之外都有效。所以我想检查传入的ID是否在对象CompanyAddress的Tag列表中。

有没有人知道这里有什么问题?

** SQL AND ANDREW WITHTAKERS SOLUTION **

SELECT this_.Id as y0_,

ca1_.Id as y1_,
this_.Name as y2_,
ca1_.IdAddressType as y3_,
ca1_.Street as y4_,
ca1_.Number as y5_, 
ca1_.ZipCode as y6_, 
ca1_.City as y7_, 
ca1_.Country as y8_, 
ca1_.Email as y9_, 
ca1_.Fax as y10_, 
ca1_.PhoneNumber as y11_, 
ca1_.CellNumber as y12_, 
ca1_.Url as y13_, 
@p0 as y14_ 

FROM CON_Company this_ inner join CON_CompanyAddress ca1_ on this_.Id=ca1_.IdCompany 
inner join CON_CompanyAddrTag tagalias2_ on ca1_.Id=tagalias2_.IdCompanyAddr

WHERE ca1_.Main = @p1 and this_.Status = @p2 and tagalias2_.Id = @p3',N'@p0 int,@p1 bit,@p2 int,@p3 int',@p0=3,@p1=1,@p2=0,@p3=3

1 个答案:

答案 0 :(得分:0)

您必须加入Tag才能执行此操作:

if (_selectedTag != null)
{
    Tag tagAlias = null;

    company
        .JoinAlias(() => ca.Tags, () => tagAlias)
        .Where(() => tagAlias.Id == _selectedTag.Id)
}

(假设您希望Tag比较Id

要记住的关于QueryOver / Criteria的事情是,它最终会变成SQL。从SQL查询内部调用ca.Tags.Select(...)没有意义,因为那里隐含JOINTag

此外,您正在混合使用QueryOver和Criteria语法,这有点令人困惑。我稍微做了一些工作:

Company companyAlias = null;

var company = Session.QueryOver<Company>(() => companyAlias)
    .JoinAlias(c => c.Addresses, () => ca)
    .Where(() => ca.Main)
    .Where(c => c.Status == ContactStatus.Approved)
    .Select(
        Projections.Property(() => companyAlias.Id).WithAlias(() => sri.TopId),
        Projections.Property(() => ca.Id).WithAlias(() => sri.Id),
        Projections.Property(() => companyAlias.Name).WithAlias(() => sri.Name),
        Projections.Property(() => ca.Address).WithAlias(() => sri.Address),
        Projections.Property(() => ca.ContactData).WithAlias(() => sri.ContactData),
        Projections.Constant(ContactClassType.Company).WithAlias(() => sri.Type)
    );