Nhibernate 具有自定义投影和查询参数的查询版本
我在一个具有属性的类中定义了一个查询,但是我试图使用该属性构建一个相当复杂的查询,并且遇到NHibernate告诉我它无法解析属性:DueDate 我的查询类如下所示:Nhibernate 具有自定义投影和查询参数的查询版本,nhibernate,queryover,Nhibernate,Queryover,我在一个具有属性的类中定义了一个查询,但是我试图使用该属性构建一个相当复杂的查询,并且遇到NHibernate告诉我它无法解析属性:DueDate 我的查询类如下所示: public class SomeQuery { public DateTime DueDate { get; private set; } public SomeQuery(DateTime dueDate) { DueDate = dueDate; } public QueryOver GetQue
public class SomeQuery {
public DateTime DueDate { get; private set; }
public SomeQuery(DateTime dueDate) {
DueDate = dueDate;
}
public QueryOver GetQueryOver() {
PrimaryObject po = null;
SubObject so = null;
return QueryOver.Of<PrimaryObject>(() => po)
.JoinAlias(() => so.SubObjects, () => so)
.Where(
Restrictions.Le(
DateProjections.DateDiff("d", () so.Value, () = DueDate),
0
)
);
}
}
对于映射,您可以假设这些字段以合理的方式映射到数据库,因为我觉得这不是问题所在
当我尝试在测试中使用此查询时,如下所示:
public class PrimaryObject {
public virtual Guid Id { get; set; }
public List<SubObject> Implementations { get; set; }
}
public class SubObject {
public virtual Guid Id { get; set; }
public virtual string Value { get; set; }
}
var testDate = new DateTime(2015, 06, 01);
IEnumerable<PrimaryObject> result = repository.FindAll(new SomeQuery(testDate));
很明显,我有一个未映射的属性,这导致投影有烧心
正在寻找一个最小的仪式解决方案来映射决斗日期。我看了安德鲁的例子,但这感觉像很多仪式
我也在谷歌上搜索解决方案,但我的google foo让我失望了
建议?解决方案?博客上的
DateDiff
实现假设您希望计算数据库字段之间的差异。这不是您想要的:您想要将一个数据库字段与一个常量进行比较
您必须重构DateProjections
方法集,以便将常量作为参数传递:
public static class DateProjections
{
private const string DateDiffFormat = "datediff({0}, ?1, ?2)";
// Here's the overload you need
public static IProjection DateDiff
(
string datepart,
Expression<Func<object>> startDate,
DateTime endDate
)
{
return DateDiff(
datePart,
Projections.Property(startDate),
Projections.Constant(endDate)
);
}
// Keeping Andrew Whitaker's original signature
public static IProjection DateDiff
(
string datepart,
Expression<Func<object>> startDate,
Expression<Func<object>> endDate
)
{
return DateDiff(
datePart,
Projections.Property(startDate),
Projections.Property(endDate)
);
}
// Added a function that's shared by
// all of the overloads
public static IProjection DateDiff(
string datepart,
IProjection startDate,
IProjection endDate)
{
// Build the function template based on the date part.
string functionTemplate = string.Format(DateDiffFormat, datepart);
return Projections.SqlFunction(
new SQLFunctionTemplate(NHibernateUtil.Int32, functionTemplate),
NHibernateUtil.Int32,
startDate,
endDate);
}
}
公共静态类
{
private const string DateDiffFormat=“datediff({0},1,2)”;
//这是你需要的超负荷
公共静态IProjectionDateDiff
(
字符串日期部分,
表达式开始日期,
日期时间结束日期
)
{
返回日期差异(
日期部分,
物业(起始日期),
预测.常数(截止日期)
);
}
//保留安德鲁·惠特克的原始签名
公共静态IProjectionDateDiff
(
字符串日期部分,
表达式开始日期,
表达式结束日期
)
{
返回日期差异(
日期部分,
物业(起始日期),
预测.财产(截止日期)
);
}
//添加了一个由共享的函数
//所有的重载
公共静态IProjectionDateDiff(
字符串日期部分,
I项目开工日期,
i项目结束日期)
{
//基于日期部分构建函数模板。
string functionTemplate=string.Format(DateDiffFormat,datepart);
return.SqlFunction(
新的SQLFunctionTemplate(NHibernateUtil.Int32,functionTemplate),
NHibernateUtil.Int32,
开始日期,
结束日期);
}
}
现在您可以这样调用它:
public QueryOver GetQueryOver() {
PrimaryObject po = null;
SubObject so = null;
return QueryOver.Of<PrimaryObject>(() => po)
.JoinAlias(() => so.SubObjects, () => so)
.Where(
Restrictions.Le(
DateProjections.DateDiff("d", () => so.Value, DueDate),
0
)
);
}
public QueryOver GetQueryOver(){
PrimaryObject po=null;
子对象so=null;
返回(()=>po)的查询版本
.JoinAlias(()=>so.SubObjects,()=>so)
.在哪里(
限制(
DateProjections.DateDiff(“d”,()=>so.Value,DueDate),
0
)
);
}
这是DateDiff调用的实际代码吗?它看起来不像是可编译的c#代码。它是可编译的,我只是减少了连接的数量,并从我的原始代码中删除了where's,直到我有了一个最小的可编译子集,但代码是不完整的。与cargo culting不同,其他人的代码没有真正理解它在做什么。您的示例扩展了我在处理QueryOver和Projections时的理解。
public QueryOver GetQueryOver() {
PrimaryObject po = null;
SubObject so = null;
return QueryOver.Of<PrimaryObject>(() => po)
.JoinAlias(() => so.SubObjects, () => so)
.Where(
Restrictions.Le(
DateProjections.DateDiff("d", () => so.Value, DueDate),
0
)
);
}