Reputation: 2287
I have a problem with duplicated results in list for my query.
What I have is two FetchMany
on a method for my repository:
public IQueryable<MyEntity> Query()
{
return Session.Query<MyEntity>()
.FetchMany(x => x.ListA)
.FetchMany(x => x.ListB);
}
Query:
var result = _myEntityRepository
.Query()
.Where(x => names.Contains(x.Name))
.Where(x => x.ListA.Any(m => listAIds.Contains(m.Id)))
.Where(x => x.ListB.Any(m => listBIds.Contains(m.Id)))
.OrderBy(x => x.CreationDate)
.ToList();
Mapping:
HasManyToMany(x => x.ListA)
.Table("MY_ENTITY_TYPE_A")
.ParentKeyColumn("MYENTITY_ID")
.ChildKeyColumn("MYENTITYA_ID")
.Fetch.Join();
ListA
is class MyEntityA with several properties.
ListB
is class MyEntityB with several properties.
The SQL produced is good and gets the values I need, how ever the values added to ListA
and ListB
gets duplicated several times. ListA and ListB are seperate tables (many to many).
I use fluent-nhibernate
.
I looked up using ToFuture
but that only gave me Method Not Implemented Exception
and I don't want to use NHibernate outside my repository.
Here is what I tried:
public IQueryable<MyEntity> Query()
{
var query = Session.Query<MyEntity>();
Session.Query<MyEntity>().FetchMany(x => x.ListA).ToFuture();
Session.Query<MyEntity>().FetchMany(x => x.ListB).ToFuture();
return query;
}
Exception is thrown at:
Session.Query<MyEntity>().FetchMany(x => x.ListA).ToFuture();
TargetInvocationException
is thrown with inner exception "The method or operation is not implemented."
Stack trace:
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at NHibernate.Linq.DefaultQueryProvider.ExecuteFutureQuery(NhLinqExpression nhLinqExpression, IQuery query, NhLinqExpression nhQuery)
at NHibernate.Linq.DefaultQueryProvider.ExecuteFuture(Expression expression)
at NHibernate.Linq.LinqExtensionMethods.ToFuture[T](IQueryable`1 query)
How can accomplish this? At the moment I do Disctint
on ListA and ListB, but it seems to be slower and not so nice with all the duplicated values in the entities created.
MyEntity has many items of EntityA in ListA and many items of EntityB in ListB, but there are no duplicates in the database.
Note: I have to use FetchMany for both, else there will be too many select queries!
Upvotes: 1
Views: 892
Reputation: 4977
Getting ToFuture
to work will be important. x.ListA
X x.ListB
is a Cartesian product. ToFuture
should work. Can you provide more details on your attempt at using it?
Ignoring the Cartesian product, you can get your current approach to work by using <set/>
instead of <bag/>
when mapping ListA
and ListB
. This tells NHibernate that the collections should not contain duplicates. Normally this wouldn't be necessary, but including both ListA
and ListB
in the same query is creating the duplicate results. <set/>
should fix this.
Upvotes: 1