Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This is an issue with NHibernate which they won't fix.</p> <p>You can get the result correct on the first level by applying the DistinctEntityTransformer, this is a built in transformer in the NHibernate and u should apply it to the queryover object using </p> <pre><code>QueryOver.TranformUsing(Tranformers.DistinctEntityTransformer). </code></pre> <p>On multilevel such as your problem you will need to write your own transformer and use it instead of the distinct entity transformer. you can use similar logic to the distinct entity transformer provided by NHibernate to fix the replications at the details.</p> <p>Edit: Here is an implementation of this:</p> <pre><code>public class MultiLevelDistinctEntityTransformer : IResultTransformer { private readonly Dictionary&lt;Type, List&lt;String&gt;&gt; _fetchedCollectionProperties; // used to know which properties are fetched so you don't fetch more details than required public MultiLevelDistinctEntityTransformer(Dictionary&lt;Type, List&lt;String&gt;&gt; fetchedCollectionProperties) { _fetchedCollectionProperties = fetchedCollectionProperties; } public object TransformTuple(object[] tuple, string[] aliases) { return tuple.Last(); } public IList TransformList(IList list) { if (list.Count == 0) return list; var result = (IList) Activator.CreateInstance(list.GetType()); var distinctSet = new HashSet&lt;Entity&gt;(); foreach (object item in list) { var entity = item as Entity; // Entity is the base class of my nhibernate classes if (entity == null) continue; if (distinctSet.Add(entity)) { result.Add(item); HandleItemDetails(item); } } return result; } private void HandleItemDetails(object item) { IEnumerable&lt;PropertyInfo&gt; collectionProperties = item.GetType().GetProperties().Where( prop =&gt; prop.IsCollectionProperty()/*extension method which checks if the object inherits from ICollection*/ &amp;&amp; _fetchedCollectionProperties.ContainsKey(item.GetType()) &amp;&amp;// get only the fetched details _fetchedCollectionProperties[item.GetType()].Contains(prop.Name)); foreach (PropertyInfo collectionProperty in collectionProperties) { dynamic detailList = collectionProperty.GetValue(item, null); if (detailList != null) { dynamic uniqueValues = Activator.CreateInstance( typeof (List&lt;&gt;).MakeGenericType(collectionProperty.PropertyType.GetGenericArguments()[0])); var distinct = new HashSet&lt;Entity&gt;(); foreach (var subItem in detailList) { var entity = subItem as Entity; if (distinct.Add(entity)) { uniqueValues.Add(subItem); HandleItemDetails(subItem); } } collectionProperty.SetValue(item, uniqueValues, null); } } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload