【问题标题】:Querying Many-To-Many relationship with Hibernate Criteria API使用 Hibernate Criteria API 查询多对多关系
【发布时间】:2010-10-17 21:04:24
【问题描述】:

我有以下多对多关系:File 1 --- * File_Insurer * --- 1 Insurer。我正在尝试使用 Criteria API(活动记录)查询此关系,以获取符合所有指定保险公司的文件(获取所有文件,其中 Insurer.Id == 2Insurer.Id == 3)。

映射文件(部分)

文件

[HasAndBelongsToMany(typeof(Insurer),
Table = "Insurer_File", ColumnKey = "IdFile", ColumnRef = "IdInsurer")]
public virtual IList<Insurer> Insurers
{
get { return insurers; }
set { insurers = value; }
}

保险公司

[HasAndBelongsToMany(typeof(File),
Table = "Insurer_File", ColumnKey = "IdInsurer", ColumnRef = "IdFile")]
public virtual IList<File> Files
{
get { return files; }
set { files = value; }
}

我尝试了很多选择

DetachedCriteria dc = DetachedCriteria.For<File>();
dc.SetResultTransformer(new DistinctRootEntityResultTransformer());
dc.CreateCriteria("Insurers").Add(Expression.Eq("Id", long.Parse("2")));
dc.CreateCriteria("Insurers").Add(Expression.Eq("Id", long.Parse("3")));
List<File> searchResults = File.FindAll(dc).ToList<File>();

这给了我一个错误:duplicate association path: Insurers

下一个选项

DetachedCriteria dc = DetachedCriteria.For<File>();
dc.SetResultTransformer(new DistinctRootEntityResultTransformer());
dc.CreateCriteria("Insurers").Add(Expression.And(Expression.Eq("Id", long.Parse("3")), Expression.Eq("Id", long.Parse("2"))));
List<File> searchResults = File.FindAll(dc).ToList<File>();

结果列表是空的(但不应该是)。

下一个带有别名的选项

DetachedCriteria dc = DetachedCriteria.For<File>();
dc.SetResultTransformer(new DistinctRootEntityResultTransformer());
dc.CreateAlias("Insurers", "i").Add(Expression.Eq("i.Id", long.Parse("2"))).Add(Expression.Eq("i.Id", long.Parse("3")));
List<File> searchResults = File.FindAll(dc).ToList<File>();

结果列表又是空的——奇怪。

下一次尝试

DetachedCriteria dc = DetachedCriteria.For<File>();
dc.SetResultTransformer(new DistinctRootEntityResultTransformer());
List<long> insurerIds = new List<long>();
insurerIds.Add(2);
insurerIds.Add(3);
dc.CreateCriteria("Insurers").Add(Expression.In("Id", insurerIds));
List<File> searchResults = File.FindAll(dc).ToList<File>();

这在某种程度上可行,但结果集包含所有可能的选项 (OR) - 这不是完全匹配。

【问题讨论】:

    标签: hibernate activerecord nhibernate


    【解决方案1】:

    这是answered already - 请参阅下面的我的看法。 hibernate 站点似乎已关闭,但请查看 Hibernate 用户指南第 11 章 HQL 的副本。

    public List<Files> findFilesForInsurers(Insurer... insurers) {
        StringBuilder hql = new StringBuilder();
        hql.append("select f from Files ff where 1=1 ");
        for (int i = 0; i < insurers.length; i++) {
            hql.append(String.format(" and :i%d in elements(ff.insurers)", i));
        }
        Query query = getSession().createQuery(hql.toString());
        for (int i = 0; i < insurers.length; i++) {
            query.setParameter("i" + i, insurers[i]);
        }
        return query.list();
    }
    

    这样提供 HQL:

    select f from Files ff where 1=1
        and :i1 in elements(ff.insurers)
        and :i2 in elements(ff.insurers)
    

    我怀疑你试图实现的 SQL 是这样的,虽然我不能确切地告诉你上面的 HQL 翻译成什么......

    select f.* from files f
        left outer join files_insurers fi1 on fi1.files_id = f.id
        left outer join files_insurers fi2 on fi2.files_id = f.id
    where 1 = 1
        and fi1.insurers_id = :i1
        and fi2.insurers_id = :i2;
    

    【讨论】:

      猜你喜欢
      • 2010-09-20
      • 2010-12-18
      • 1970-01-01
      • 1970-01-01
      • 2017-01-20
      • 1970-01-01
      • 2013-07-16
      • 1970-01-01
      • 2015-07-20
      相关资源
      最近更新 更多