A correct way to load entities by Id list when Id is not mapped
-
21-09-2019 - |
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?
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