I've the following many to many relation: File 1 --- * File_Insurer * --- 1 Insurer. I'm trying to query this relation using the Criteria API (Active Record) to get Files that meet ALL specified Insurers (Get all Files where Insurer.Id == 2 AND Insurer.Id == 3).
Mapping files (parts):
File
[HasAndBelongsToMany(typeof(Insurer), Table = "Insurer_File", ColumnKey = "IdFile", ColumnRef = "IdInsurer")] public virtual IList Insurers { get { return insurers; } set { insurers = value; } }
Insurer
[HasAndBelongsToMany(typeof(File), Table = "Insurer_File", ColumnKey = "IdInsurer", ColumnRef = "IdFile")] public virtual IList Files { get { return files; } set { files = value; } }
I've tried many options:
DetachedCriteria dc = DetachedCriteria.For(); 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 searchResults = File.FindAll(dc).ToList();
That gives me a error "duplicate association path: Insurers".
Next option:
DetachedCriteria dc = DetachedCriteria.For(); dc.SetResultTransformer(new DistinctRootEntityResultTransformer()); dc.CreateCriteria("Insurers").Add(Expression.And(Expression.Eq("Id", long.Parse("3")), Expression.Eq("Id", long.Parse("2")))); List searchResults = File.FindAll(dc).ToList();
The result list is empty (but shouldn't).
Next option with alias:
DetachedCriteria dc = DetachedCriteria.For(); 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 searchResults = File.FindAll(dc).ToList();
The result list is empty again - strange.
Next try:
DetachedCriteria dc = DetachedCriteria.For(); dc.SetResultTransformer(new DistinctRootEntityResultTransformer()); List insurerIds = new List(); insurerIds.Add(2); insurerIds.Add(3); dc.CreateCriteria("Insurers").Add(Expression.In("Id", insurerIds)); List searchResults = File.FindAll(dc).ToList();
This works somehow, but the result set contains a all possible options (OR) - it's not an exact match.