问题
could someone help me to translate LINQ expression to Nhibernate QueryOver
from m in messages
where !m.Recipients.Any(rcpt => rcpt.IsDeleted && rcpt.User = user)
I tried this
var qry = Session.QueryOver<UserMessage>();
qry.Where(m => m.Recipients.Any(r => !r.IsDeleted && r.User == user));
but got
System.Exception : Unrecognised method call: System.Linq.Enumerable:Boolean Any[TSource](System.Collections.Generic.IEnumerable1[TSource], System.Func
2[TSource,System.Boolean]
回答1:
!m.Recipients.Any(...)
translates to a "not exists" sub-query. You will need a couple of aliases to correlate the sub-query with the main query, and the sub-query will need to have a projection to make NHibernate happy.
Try something like this:
UserMessage messageAlias = null;
UserMessage recipientMessageAlias = null;
var subquery = QueryOver.Of<MessageRecipient>()
.JoinAlias(x => x.Message, () => recipientMessageAlias)
.Where(x => x.IsDeleted == true) // your criteria
.Where(x => x.User.Id == userId)
.Where(() => recipientMessageAlias.Id == messageAlias.Id) // correlated subquery
.Select(x => x.Id); // projection
var query = session.QueryOver(() => messageAlias)
.Where(Subqueries.WhereNotExists(subquery));
return query.List();
回答2:
I managed to it this way:
UserMessage messageAlias = null;
var qry = Session.QueryOver<UserMessage>(() => messageAlias);
UserMessageRecipient recipientAlias = null;
var deletedbyUser = QueryOver.Of(() => recipientAlias)
.Select(x => x.Id)
.Where( () => recipientAlias.Message.Id == messageAlias.Id
&& (recipientAlias.Recipient == query.User && recipientAlias.IsDeleted))
.DetachedCriteria;
qry.Where(Subqueries.NotExists(deletedbyUser));
回答3:
Try to use the Linq version with session.Query<> instead of QueryOver
var qry = Session.Query<UserMessage>();
qry.Where(m => m.Recipients.Any(r => !r.IsDeleted && r.User == user));
来源:https://stackoverflow.com/questions/7370205/nhibernate-queryover-association-does-not-contain-item