X与Y的多对多关系 - 如何获得所有已定义Y属性的X

时间:2015-05-04 00:03:48

标签: c# hibernate nhibernate fluent-nhibernate

公司与行业类型有多对多的关系。也就是说,公司可以拥有多种行业类型,并且可以为许多公司分配行业类型。

将IEnumerable(称为industryTypes)传递给应该返回IEnumerable的方法。这些公司必须遵守以下规则:

  • 返回的公司必须拥有输入中的所有industryTypeNames。
  • 返回的公司可以拥有比输入定义的更多行业类型,但输入定义的所有行业类型必须存在。

我尝试了许多不同的方法,但我保存了这些方法以获得示例:

var industryTypeNames = industryTypes.Select(x => x.Name).Distinct();

整个结构并不重要。所有映射都在起作用。

课程有:

public class Company
{
    Guid Id;
    IList<IndustryType> IndustryTypes;
}

public class IndustryType
{
    Guid Id;
    string Name;
    IList<Company> Companies;
}

映射工作正常。问题与查询有关。

以下是不起作用的实现:

       Company companyAlias = null;
       var query = Session.QueryOver<IndustryType>()
                            .WhereRestrictionOn(dbIndustryType => dbIndustryType.Name).IsIn(industryTypeNames)
                            .JoinAlias(dbIndustryType => dbIndustryType.Companies, () => companyAlias)
                            .Where(Restrictions.Eq(Projections.Count(() => companyAlias.Id), industryTypeNames.Length))
                            .Select(Projections.Group(() => companyAlias));

另一个:

        IndustryType industryTypeAlias = null;
        var query = Session.QueryOver<Company>()
                            .JoinAlias(dbCompany => dbCompany.IndustryTypes, () => industryTypeAlias)
                            .Where(Restrictions.Eq(Projections.Count(() => industryTypeAlias.Id), industryTypeNames.Length))
                            .WhereRestrictionOn(() => industryTypeAlias.Name).IsIn(industryTypeNames);

2 个答案:

答案 0 :(得分:0)

目前我已将查询分为两部分。它不是最有效的方法,但我需要阅读NHibernate文档以更有效地学习它。

当前查询:

        var query = Session.QueryOver<Company>()
                                .JoinAlias(dbCompany => dbCompany.IndustryTypes, () => industryTypeAlias)
                                .WhereRestrictionOn(() => industryTypeAlias.Name).IsIn(industryTypeNames)
                                .SelectList(list => list
                                                        .SelectGroup(dbCompany => dbCompany.Id)
                                                        .SelectCount(dbCompany => industryTypeAlias.Name))
                                .Where(Restrictions.Eq(Projections.Count<Company>(dbCompany => industryTypeAlias.Name), industryTypeNames.Length))
                                .SelectList(list => list
                                                        .SelectGroup(dbCompany => dbCompany.Id).WithAlias(() => resIndustryType.Id)
                                           )
                                .TransformUsing(Transformers.AliasToBean<DtoCompany>());

        var resultCompanyIdList = query.List().Select(company => company.Id).ToArray();

        var result = Session.QueryOver<DtoCompany>()
                                .WhereRestrictionOn(dbCompany => dbCompany.Id)
                                .IsIn(resultCompanyIdList);

        return result.List();

答案 1 :(得分:0)

结构可能无关紧要,但映射DO! 创建多对多关系涉及创建中间表以映射来自两个表的键。在Nhibernate中,你可以这样做

public class CompanyMap : ClassMap<Company>
{
    public CompanyMap()
    {
        HasManyToMany(x => x.IndustryTypes)
           .Cascade.All()
           .Table("CompaniesIndustryTypes");
    }
}

public class IndustryTypeMap : ClassMap<IndustryType>
{
    public IndustryTypeMap()
    {
        HasManyToMany(x => x.Companies)
           .Cascade.All()
           .Inverse()
           .Table("CompaniesIndustryTypes");
    }
}