Nhibernate LINQ DateTime.AddDay不起作用 [英] Nhibernate LINQ DateTime.AddDay does not work

查看:244
本文介绍了Nhibernate LINQ DateTime.AddDay不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要比较一个linq查询中的两个DateTime属性,类似于下面的一个
-

  var patients = from c in session.Query< Patient>()其中c.DateAdded.AddDays(1) c.AdmitDate select c; 

当我运行查询我得到这个异常:
System.NotSupportedException {System。 DateTime AddDays(Double)}




NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.VisitMethodCallExpression(MethodCallExpression
expression)



我看了一下Fabio的文章
http://fabiomaulo.blogspot.com/2010/07/nhibernate-linq-provider-exten ...
但是treeBuilder没有任何特定于$的功能b $ b DateTime比较。



这是示例的代码。要运行此操作,请为FluentNhibernate和SQLite安装NuGet软件包。

  using System; 
使用System.Collections.Generic;
使用System.Data.SQLite;
使用System.IO;
使用System.Linq;
使用System.Text;
使用FluentNHibernate.Cfg;
使用FluentNHibernate.Cfg.Db;
使用FluentNHibernate.Mapping;
使用NHibernate;
使用NHibernate.Cfg;
使用NHibernate.Tool.hbm2ddl;
使用NHibernate.Linq;

命名空间ConsoleApplication1
{
类程序
{
private static配置_config;

static void Main(string [] args)
{
var sessionFactory = CreateSessionFactory();
using(var session = sessionFactory.OpenSession())
{
BuildSchema(session);
使用(var transaction = session.BeginTransaction())
{
var foo = new Patient
{
Name =Foo,
Sex = Sex.Male,
DateAdded = new DateTime(2009,1,1),
AdmitDate = new DateTime(2009,1,2)
};
var bar = new Patient
{
Name =Bar,
Sex = Gender.Female,
DateAdded = new DateTime(2009,1,1)
AdmitDate = new DateTime(2009,1,2)
};
session.SaveOrUpdate(foo);
session.SaveOrUpdate(bar);
transaction.Commit();
}
session.Flush();

使用(session.BeginTransaction())
{
var cats = from c in session.Query< Patient>()where
c.DateAdded.AddDays 1) c.AdmitDate select c;
foreach(猫猫中的猫猫)
{
Console.WriteLine(patient name {0},sex {1},cat.Name,
cat.Sex);
}
}
}
Console.ReadKey();
}

private static ISessionFactory CreateSessionFactory()
{
return Fluently.Configure()
.Database(
SQLiteConfiguration.Standard.InMemory ()

.Mappings(m =>
m.FluentMappings.AddFromAssemblyOf< Program>())
.ExposeConfiguration(c => _config = c)
.BuildSessionFactory();
}

private static void BuildSchema(ISession session)
{
new SchemaExport(_config)
.Execute(true,true,false,session连接,null);
}
}

public class PatientMap:ClassMap< Patient>
{
public PatientMap()
{
Id(x => x.Id);
Map(x => x.Name)
.Length(16)
.Not.Nullable();
Map(x => x.Sex);
Map(x => x.DateAdded);
Map(x => x.AdmitDate);
}
}

public class Patient
{
public virtual int Id {get;组; }
public virtual string Name {get;组; }
public virtual性别性别{get;组; }
public virtual DateTime DateAdded {get;组; }
public virtual DateTime AdmitDate {get;组; }
}

public枚举性别
{
男,

}
/ pre>

谢谢,
Vikram

解决方案

以上问题:

  using System; 
使用System.Linq;
使用System.Reflection;
使用FluentNHibernate.Cfg;
使用FluentNHibernate.Cfg.Db;
使用FluentNHibernate.Mapping;
使用NHibernate;
使用NHibernate.Cfg;
使用NHibernate.Dialect;
使用NHibernate.Dialect.Function;
使用NHibernate.Hql.Ast;
使用NHibernate.Linq.Functions;
使用NHibernate.Tool.hbm2ddl;
使用NHibernate.Linq;
使用System.Collections.ObjectModel;
使用System.Linq.Expressions;
使用NHibernate.Linq.Visitors;
使用NHibernate.Cfg.Loquacious;

命名空间ConsoleApplication1
{
类程序
{
private static配置_config;

static void Main(string [] args)
{App_Start.NHibernateProfilerBootstrapper.PreStart();

var sessionFactory = CreateSessionFactory();
using(var session = sessionFactory.OpenSession())
{
BuildSchema(session);
使用(var transaction = session.BeginTransaction())
{
var foo = new Patient
{
Name =Foo,
Sex = Sex.Male,
DateAdded = new DateTime(2009,1,4),
AdmitDate = new DateTime(2009,1,6)
};
var bar = new Patient
{
Name =Bar,
Sex = Gender.Female,
DateAdded = new DateTime(2009,1,1)
AdmitDate = new DateTime(2009,1,2)
};
session.SaveOrUpdate(foo);
session.SaveOrUpdate(bar);
transaction.Commit();
}
session.Flush();

使用(session.BeginTransaction())
{
//x.PatientVisit.AdmitDate.Value.Date == x.DateAdded.Date
var patients =来自c中的session.Query< Patient>()其中c.DateAdded.AddDays(1)< c.AdmitDate.Value select c;
foreach(var cat in patients)
{
Console.WriteLine(patient name {0},sex {1},cat.Name,cat.Sex);
}
}
}
Console.ReadKey();
}

私有静态ISessionFactory CreateSessionFactory()
{
return Fluently.Configure()
.Database(
MsSqlConfiguration.MsSql2008.Dialect< ; CustomDialect>()
.ConnectionString(Data Source =; Initial Catalog = testdb; Integrated Security = True; Connection Reset = false)

.Mappings(m =>
m.FluentMappings.AddFromAssemblyOf< Program>())
.ExposeConfiguration(c =>
{
c.LinqToHqlGeneratorsRegistry< ExtendedLinqtoHqlGeneratorsRegistry>();
_config = c;
})
.BuildSessionFactory();
}

private static void BuildSchema(ISession session)
{
new SchemaExport(_config)
.Execute(true,true,false,session连接,null);
}
}

public class PatientMap:ClassMap< Patient>
{
public PatientMap()
{
Id(x => x.Id);
Map(x => x.Name)
.Length(16)
.Not.Nullable();
Map(x => x.Sex);
Map(x => x.DateAdded);
Map(x => x.AdmitDate);
}
}

public class Patient
{
public virtual int Id {get;组; }
public virtual string Name {get;组; }
public virtual性别性别{get;组; }
public virtual DateTimeOffset DateAdded {get;组; }
public virtual DateTime? AdmitDate {get;组; }
}

public enum性别
{
男,

}

public class ExtendedLinqtoHqlGeneratorsRegistry: defaultLinqToHqlGeneratorsRegistry
{
public ExtendedLinqtoHqlGeneratorsRegistry()
{
this.Merge(new AddDaysGenerator());



public class AddDaysGenerator:BaseHqlGeneratorForMethod
{
public AddDaysGenerator()
{
SupportedMethods = new [] {
ReflectionHelper.GetMethodDefinition< DateTimeOffset?>(d =&d; d.Value.AddDays((double)0))
};
}

public override HqlTreeNode BuildHql(MethodInfo method,Expression targetObject,ReadOnlyCollection< Expression> arguments,HqlTreeBuilder treeBuilder,IHqlExpressionVisitor visitor)
{
return treeBuilder.MethodCall AddDays,
visitor.Visit(targetObject).AsExpression(),
visitor.Visit(arguments [0])。AsExpression()
);
}
}

public class CustomDialect:MsSql2008Dialect
{
public CustomDialect()
{
RegisterFunction(
AddDays,
new SQLFunctionTemplate(
NHibernateUtil.DateTime,
dateadd(day,?2,?1)

);
}
}

}


I need to compare two DateTime properties in a linq query, similar to the one below -

var patients = from c in session.Query<Patient>() where c.DateAdded.AddDays(1) < c.AdmitDate select c;

when I run the query I get this exception: System.NotSupportedException {"System.DateTime AddDays(Double)"}

at NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.VisitMethodCallExpression(MethodCallExpression expression)

I took a look at Fabio's article on http://fabiomaulo.blogspot.com/2010/07/nhibernate-linq-provider-exten... but the treeBuilder doesn't have any functions that are specific to DateTime comparisons.

Here is the code for the sample. To run this , install NuGet packages for FluentNhibernate and SQLite.

using System;
using System.Collections.Generic;
using System.Data.SQLite;
using System.IO;
using System.Linq;
using System.Text;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using FluentNHibernate.Mapping;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;
using NHibernate.Linq;

namespace ConsoleApplication1
{
    class Program
    {
            private static Configuration _config;

            static void Main(string[] args)
            {
                    var sessionFactory = CreateSessionFactory();
                    using (var session = sessionFactory.OpenSession())
                    {
                            BuildSchema(session);
                            using(var transaction = session.BeginTransaction())
                            {
                                    var foo = new Patient
                                    {
                                            Name = "Foo",
                                            Sex = Gender.Male,
                                            DateAdded = new DateTime(2009, 1, 1),
                                            AdmitDate = new DateTime(2009, 1, 2)
                                    };
                                    var bar = new Patient
                                    {
                                            Name = "Bar",
                                            Sex = Gender.Female,
                                            DateAdded = new DateTime(2009, 1, 1),
                                            AdmitDate = new DateTime(2009, 1, 2)
                                    };
                                    session.SaveOrUpdate(foo);
                                    session.SaveOrUpdate(bar);
                                    transaction.Commit();
                            }
                            session.Flush();

                            using (session.BeginTransaction())
                            {
                                    var cats = from c in session.Query<Patient>() where
c.DateAdded.AddDays(1) < c.AdmitDate select c;
                                    foreach (var cat in cats)
                                    {
                                            Console.WriteLine("patient name {0}, sex    {1}", cat.Name,
cat.Sex);
                                    }
                            }
                    }
                    Console.ReadKey();
            }

            private static ISessionFactory CreateSessionFactory()
            {
                    return Fluently.Configure()
                      .Database(
                            SQLiteConfiguration.Standard.InMemory()
                      )
                      .Mappings(m =>
                            m.FluentMappings.AddFromAssemblyOf<Program>())
                      .ExposeConfiguration(c => _config = c)
                      .BuildSessionFactory();
            }

            private static void BuildSchema(ISession session)
            {
                    new SchemaExport(_config)
                      .Execute(true, true, false, session.Connection, null);
            }
    }

    public class PatientMap : ClassMap<Patient>
    {
            public PatientMap()
            {
                    Id(x => x.Id);
                    Map(x => x.Name)
                      .Length(16)
                      .Not.Nullable();
                    Map(x => x.Sex);
                    Map(x => x.DateAdded);
                    Map(x => x.AdmitDate);
            }
    }

    public class Patient
    {
            public virtual int Id { get; set; }
            public virtual string Name { get; set; }
            public virtual Gender Sex { get; set; }
            public virtual DateTime DateAdded { get; set; }
            public virtual DateTime AdmitDate { get; set; }
    }

    public enum Gender
    {
            Male,
            Female
    } 

Thanks, Vikram

解决方案

Answer to the above question:

using System;
using System.Linq;
using System.Reflection;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using FluentNHibernate.Mapping;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Dialect;
using NHibernate.Dialect.Function;
using NHibernate.Hql.Ast;
using NHibernate.Linq.Functions;
using NHibernate.Tool.hbm2ddl;
using NHibernate.Linq;
using System.Collections.ObjectModel;
using System.Linq.Expressions;
using NHibernate.Linq.Visitors;
using NHibernate.Cfg.Loquacious;

namespace ConsoleApplication1
{
class Program
{
    private static Configuration _config;

    static void Main(string[] args)
    {App_Start.NHibernateProfilerBootstrapper.PreStart();

        var sessionFactory = CreateSessionFactory();
        using (var session = sessionFactory.OpenSession())
        {
            BuildSchema(session);
            using(var transaction = session.BeginTransaction())
            {
                var foo = new Patient
                {
                    Name = "Foo", 
                    Sex = Gender.Male, 
                    DateAdded = new DateTime(2009, 1, 4), 
                    AdmitDate = new DateTime(2009, 1, 6)
                };
                var bar = new Patient
                {
                    Name = "Bar", 
                    Sex = Gender.Female, 
                    DateAdded = new DateTime(2009, 1, 1), 
                    AdmitDate = new DateTime(2009, 1, 2)
                };
                session.SaveOrUpdate(foo);
                session.SaveOrUpdate(bar);
                transaction.Commit();
            }
            session.Flush();

            using (session.BeginTransaction())
            {
                //x.PatientVisit.AdmitDate.Value.Date == x.DateAdded.Date
                var patients = from c in session.Query<Patient>() where c.DateAdded.AddDays(1) < c.AdmitDate.Value select c; 
                foreach (var cat in patients)
                {
                    Console.WriteLine("patient name {0}, sex  {1}", cat.Name, cat.Sex);
                }
            }
        }
        Console.ReadKey();
    }

    private static ISessionFactory CreateSessionFactory()
    {
        return Fluently.Configure()
            .Database(
                MsSqlConfiguration.MsSql2008.Dialect<CustomDialect>()
                    .ConnectionString("Data Source=.;Initial Catalog=testdb;Integrated Security=True;Connection Reset=false")
            )
            .Mappings(m =>
                      m.FluentMappings.AddFromAssemblyOf<Program>())
            .ExposeConfiguration(c =>
                                    {
                                        c.LinqToHqlGeneratorsRegistry<ExtendedLinqtoHqlGeneratorsRegistry>();
                                        _config = c;
                                    })
            .BuildSessionFactory();
    }

    private static void BuildSchema(ISession session)
    {
        new SchemaExport(_config)
          .Execute(true, true, false, session.Connection, null);
    }
}

public class PatientMap : ClassMap<Patient>
{
    public PatientMap()
    {
        Id(x => x.Id);
        Map(x => x.Name)
          .Length(16)
          .Not.Nullable();
        Map(x => x.Sex);
        Map(x => x.DateAdded);
        Map(x => x.AdmitDate);
    }
}

public class Patient
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual Gender Sex { get; set; }
    public virtual DateTimeOffset DateAdded { get; set; }
    public virtual DateTime? AdmitDate { get; set; }
}

public enum Gender
{
    Male,
    Female
}

public class ExtendedLinqtoHqlGeneratorsRegistry : DefaultLinqToHqlGeneratorsRegistry
{
    public ExtendedLinqtoHqlGeneratorsRegistry()
    {
        this.Merge(new AddDaysGenerator());
    }
}

public class AddDaysGenerator : BaseHqlGeneratorForMethod
{
    public AddDaysGenerator()
    {
        SupportedMethods = new[] {
            ReflectionHelper.GetMethodDefinition<DateTimeOffset?>(d => d.Value.AddDays((double)0))
        };
    }

    public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor)
    {
        return treeBuilder.MethodCall("AddDays",
                                      visitor.Visit(targetObject).AsExpression(),
                                      visitor.Visit(arguments[0]).AsExpression()
                                      );
    }
}

public class CustomDialect : MsSql2008Dialect
{
    public CustomDialect()
    {
        RegisterFunction(
            "AddDays",
            new SQLFunctionTemplate(
                NHibernateUtil.DateTime,
                "dateadd(day,?2,?1)"
                )
            );
    }
}

}

这篇关于Nhibernate LINQ DateTime.AddDay不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆