我有以下多对多关系:File 1 --- * File_Insurer * --- 1 Insurer
。我正在尝试使用Criteria API(Active Record)查询此关系,以获取符合所有指定保险公司的文件(获取Insurer.Id == 2
和Insurer.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) - 它不是完全匹配。
答案 0 :(得分:0)
这是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;