Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>After looking at the sources for NHibernate, I'm fairly sure that there exists no such functionality.</p> <p><em>I wouldn't mind, however, for someone to prove me wrong.</em></p> <p><strong>In my specific setting</strong>, I did solve this problem by writing a method that takes a couple of lambdas (representing the key column, and an optional column to filter by - all properties of a specific domain entity). This method then builds the sql and calls <code>session.CreateSQLQuery(...).UniqueResult();</code> I'm not claiming that this is a general purpose solution.</p> <p>To avoid the use of magic strings, I borrowed a copy of <code>PropertyHelper&lt;T&gt;</code> from <a href="https://stackoverflow.com/questions/491429/how-to-get-the-propertyinfo-of-a-specific-property/491486#491486">this answer</a>.</p> <p>Here's the code:</p> <pre><code>public abstract class RepositoryBase&lt;T&gt; where T : DomainEntityBase { public long GetIndexOf&lt;TUnique, TWhere&gt;(T entity, Expression&lt;Func&lt;T, TUnique&gt;&gt; uniqueSelector, Expression&lt;Func&lt;T, TWhere&gt;&gt; whereSelector, TWhere whereValue) where TWhere : DomainEntityBase { if (entity == null || entity.Id == Guid.Empty) { return -1; } var entityType = typeof(T).Name; var keyField = PropertyHelper&lt;T&gt;.GetProperty(uniqueSelector).Name; var keyValue = uniqueSelector.Compile()(entity); var innerWhere = string.Empty; if (whereSelector != null) { // Builds a column name that adheres to our naming conventions! var filterField = PropertyHelper&lt;T&gt;.GetProperty(whereSelector).Name + "Id"; if (whereValue == null) { innerWhere = string.Format(" where [{0}] is null", filterField); } else { innerWhere = string.Format(" where [{0}] = :filterValue", filterField); } } var innerQuery = string.Format("(select [{0}], row_number() over (order by {0}) as RowNum from [{1}]{2}) X", keyField, entityType, innerWhere); var outerQuery = string.Format("select RowNum from {0} where {1} = :keyValue", innerQuery, keyField); var query = _session .CreateSQLQuery(outerQuery) .SetParameter("keyValue", keyValue); if (whereValue != null) { query = query.SetParameter("filterValue", whereValue.Id); } var sqlRowNumber = query.UniqueResult&lt;long&gt;(); // The row_number() function is one-based. Our index should be zero-based. sqlRowNumber -= 1; return sqlRowNumber; } public long GetIndexOf&lt;TUnique&gt;(T entity, Expression&lt;Func&lt;T, TUnique&gt;&gt; uniqueSelector) { return GetIndexOf(entity, uniqueSelector, null, (DomainEntityBase)null); } public long GetIndexOf&lt;TUnique, TWhere&gt;(T entity, Expression&lt;Func&lt;T, TUnique&gt;&gt; uniqueSelector, Expression&lt;Func&lt;T, TWhere&gt;&gt; whereSelector) where TWhere : DomainEntityBase { return GetIndexOf(entity, uniqueSelector, whereSelector, whereSelector.Compile()(entity)); } } public abstract class DomainEntityBase { public virtual Guid Id { get; protected set; } } </code></pre> <p>And you use it like so:</p> <pre><code>... public class Book : DomainEntityBase { public virtual string Title { get; set; } public virtual Category Category { get; set; } ... } public class Category : DomainEntityBase { ... } public class BookRepository : RepositoryBase&lt;Book&gt; { ... } ... var repository = new BookRepository(); var book = ... a persisted book ... // Get the index of the book, sorted by title. var index = repository.GetIndexOf(book, b =&gt; b.Title); // Get the index of the book, sorted by title and filtered by that book's category. var indexInCategory = repository.GetIndexOf(book, b =&gt; b.Title, b =&gt; b.Category); </code></pre> <p>As I said, this works for me. I'll definitely tweak it as I move forward. YMMV.</p> <p>Now, if the OP has solved this himself, then I would love to see his solution! :-)</p>
    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. 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