Question

I have the following code

string idName = builder.IdentifierName;
Disjunction disjunction = Restrictions.Disjunction();
IList ids = new ArrayList(entityInfos.Length);
foreach (var entityInfo in entityInfos)
{
    ids.Add(entityInfo .Id);
}
disjunction.Add(Restrictions.In(idName, ids));
criteria.Add(disjunction);
criteria.List();

(I haven't written it, it's simplified code from NHibernate.Search)

Value of idName is correct ("Id").

In my mapping I do not have Id mapped to an entity property, it is DB-only:

<id column="Id" type="int">
  <generator class="native" />
</id>

When I run the code, it throws an exception:

[QueryException: could not resolve property: Id of: MyType]
   NHibernate.Persister.Entity.AbstractPropertyMapping.ToType(String propertyName) +326
   NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetTypeUsingProjection(ICriteria subcriteria, String propertyName) +416
   NHibernate.Criterion.InExpression.AssertPropertyIsNotCollection(ICriteriaQuery criteriaQuery, ICriteria criteria) +41
   NHibernate.Criterion.InExpression.ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary`2 enabledFilters) +49
   NHibernate.Criterion.Junction.ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary`2 enabledFilters) +448
   NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetWhereCondition(IDictionary`2 enabledFilters) +354
   NHibernate.Loader.Criteria.CriteriaJoinWalker..ctor(IOuterJoinLoadable persister, CriteriaQueryTranslator translator, ISessionFactoryImplementor factory, ICriteria criteria, String rootEntityName, IDictionary`2 enabledFilters) +516
   NHibernate.Loader.Criteria.CriteriaLoader..ctor(IOuterJoinLoadable persister, ISessionFactoryImplementor factory, CriteriaImpl rootCriteria, String rootEntityName, IDictionary`2 enabledFilters) +220
   NHibernate.Impl.SessionImpl.List(CriteriaImpl criteria, IList results) +364
   NHibernate.Impl.CriteriaImpl.List(IList results) +63
   NHibernate.Impl.CriteriaImpl.List() +46

What is the correct way to create a restriction and criteria so that I can search by Id even if it is not mapped?

Was it helpful?

Solution

Try IdEq instead. It needs another Disjunction.

Disjunction idsRestriction = Restrictions.Disjunction();
entityInfo
  .Select(x => x.Id)
  .ToList()
  .ForEach(id => idsRestriction.Add(Restriction.IdEq(id)));
disjunction.Add(idsRestriction);

Note: this will produce something like (id = 1 OR id = 2 OR id = 3 ...) instead of (id IN (1, 2, 3).

Not hundred percent sure if it works, but it should.

OTHER TIPS

You can use IdEq, or use the keyword "id" (all lower case) to refer to the primary key

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top