Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Nhibernate 具有自定义投影和查询参数的查询版本_Nhibernate_Queryover - Fatal编程技术网

Nhibernate 具有自定义投影和查询参数的查询版本

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

我在一个具有属性的类中定义了一个查询,但是我试图使用该属性构建一个相当复杂的查询,并且遇到NHibernate告诉我它无法解析属性:DueDate

我的查询类如下所示:

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
        )
  );
}