是否可以重构此nHibernate Linq查询
本文关键字:nHibernate Linq 查询 重构 是否 | 更新日期: 2023-09-27 18:27:15
目前我有以下代码:
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
....
}
正如您所看到的,除了publicationType条件之外,每次查询都是相同的。我试图通过创建一个使用Func的方法来重构它,例如
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;
}
然后像一样调用这个方法
GetPublicationItems(IsBook);
但当我这样做时,我会得到错误:InvalidCastException:无法将"NHibernate.Hql.Ast.HqlParameter"类型的对象强制转换为"NHibeernate.Hql.Ast.HqlBooleanExpression"类型。
有别的办法吗?
听起来你并不真的需要一个函数——你只需要一个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
{
...
});
}
如果真的需要它更通用,那么您可能只需要更改代码,使用表达式树而不是委托(并更改输入类型):
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
{
...
});
}
不过,此时您将无法用GetPublicationItems(IsBook)
来调用它。你可以做:
GetPublicationItems(p => p.PublicationType == PublicationType.Book)
或者:
private static readonly Expression<Func<Publication, bool>> IsBook =
p => p.PublicationType == PublicationType.Book;
...
GetPublicationItems(IsBook)
是否有原因不能在查询中仅使用publicationType?
return Session.Query<Publication>()
.Where(p => p.PublicationType == publicationType)
.OrderByDescending(p => p.DateApproved)
.Take(10)
.Select(p => new PublicationViewModel
{
...
});
您的错误是将委托与表达式树混淆。
Func是一个委托,不能转换为SQL。你可以这样写:
Session.Query<Publication>()
.Where(p => p.PublicationType == yourPubilcationType)
...
或者,如果你想通过一个过滤器,就像你在样本中暗示的那样:
IEnumerable<PublicationViewModel> GetPublicationItems(Expression<Func<PublicationType, bool>> pubQuery)
{
return Session.Query<Publication>()
.Where(pubQuery)
.OrderByDescending(p => p.DateApproved)
.Take(10)
.Select(p => new PublicationViewModel
{
...
});
}