Can I reorganize this nHibernate Linq query?

I currently have the following code:

switch (publicationType) { case PublicationType.Book: return Session.Query<Publication>() .Where(p => p.PublicationType == PublicationType.Book) .OrderByDescending(p => p.DateApproved) .Take(10) .Select(p => new PublicationViewModel { ... }); case PublicationType.Magazine: return Session.Query<Publication>() .Where(p => p.PublicationType == PublicationType.Magazine) .OrderByDescending(p => p.DateApproved) .Take(10) .Select(p => new PublicationViewModel { ... }); case PublicationType.Newspaper .... } 

As you can see, the request is the same every time, except for the publishType condition. I tried to reorganize this by creating a method that accepts Func, for example.

 private IEnumerable<PublicationViewModel> GetPublicationItems(Func<PublicationType, bool>> pubQuery) { return Session.Query<Publication>() .Where(pubQuery) .OrderByDescending(p => p.DateApproved) .Take(10) .Select(p => new PublicationViewModel { ... }); } private bool IsBook(PublicationType publicationType) { return publicationType == PublicationType.Book; } 

and then calling this method, for example

 GetPublicationItems(IsBook); 

But when I do this, I get the error: InvalidCastException: it is not possible to drop an object like "NHibernate.Hql.Ast.HqlParameter" to enter "NHibernate.Hql.Ast.HqlBooleanExpression".

Is there any other way to do this?

+6
source share
3 answers

It sounds like you really don't need a function - you just need a PublicationType :

 private IEnumerable<PublicationViewModel> GetPublicationItems(PublicationType type) { return Session.Query<Publication>() .Where(p => p.PublicationType == type) .OrderByDescending(p => p.DateApproved) .Take(10) .Select(p => new PublicationViewModel { ... }); } 

If you really need this more general, you probably just need to change your code to use the expression tree instead of the delegate (and change the input type):

 private IEnumerable<PublicationViewModel> GetPublicationItems( Expression<Func<Publication, bool>> pubQuery) { return Session.Query<Publication>() .Where(pubQuery) .OrderByDescending(p => p.DateApproved) .Take(10) .Select(p => new PublicationViewModel { ... }); } 

You cannot call it with GetPublicationItems(IsBook) at this point. You can do:

 GetPublicationItems(p => p.PublicationType == PublicationType.Book) 

Or:

 private static readonly Expression<Func<Publication, bool>> IsBook = p => p.PublicationType == PublicationType.Book; ... GetPublicationItems(IsBook) 
+5
source

Is there a reason why you cannot just use the publication type in the request?

 return Session.Query<Publication>() .Where(p => p.PublicationType == publicationType) .OrderByDescending(p => p.DateApproved) .Take(10) .Select(p => new PublicationViewModel { ... }); 
0
source

Your mistake confused delegates with expression trees.

Func is a delegate that cannot be converted to SQL. You could simply write it like this:

 Session.Query<Publication>() .Where(p => p.PublicationType == yourPubilcationType) ... 

Or, if you want to pass a filter, this method, as you hinted in your example:

 IEnumerable<PublicationViewModel> GetPublicationItems(Expression<Func<PublicationType, bool>> pubQuery) { return Session.Query<Publication>() .Where(pubQuery) .OrderByDescending(p => p.DateApproved) .Take(10) .Select(p => new PublicationViewModel { ... }); } 
0
source

Source: https://habr.com/ru/post/910272/


All Articles