[英]Is it possible to refactor this nHibernate Linq query?
目前我有以下代码:
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'的对象强制转换为'NHibernate.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
{
...
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.