Nhibernate LINQ DateTime.AddDay不起作用 [英] Nhibernate LINQ DateTime.AddDay does not work
问题描述
我需要比较一个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;
/ pre>
使用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枚举性别
{
男,
女
}
谢谢,
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屋!