如何比较在 ICompositeUserType 的 NHibernate ICriteria 查询中使用 .NET 类型?
我有一个已回答的 StackOverflow 问题,涉及如何将旧版 CHAR
数据库日期和时间字段合并到 POCO 中的一个 .NET DateTime
属性中 这里(非常感谢Berryl!)。现在我试图获取一个自定义 ICritera 查询来针对该 DateTime
属性进行操作,但无济于事。这是我的查询:
ICriteria criteria =
Session.CreateCriteria<InputFileLog>()
.Add(Expression.Gt(MembersOf<InputFileLog>.GetName(x => x.FileCreationDateTime), DateTime.Now.AddDays(-14)))
.AddOrder(Order.Desc(Projections.Id()))
.CreateCriteria(typeof(InputFile).Name)
.Add(Expression.Eq(MembersOf<InputFile>.GetName(x => x.Id), inputFileName));
IList<InputFileLog> list = criteria.List<InputFileLog>();
这是它生成的查询:
SELECT this_.input_file_token as input1_9_2_,
this_.file_creation_date as file2_9_2_,
this_.file_creation_time as file3_9_2_,
this_.approval_ind as approval4_9_2_,
this_.file_id as file5_9_2_,
this_.process_name as process6_9_2_,
this_.process_status as process7_9_2_,
this_.input_file_name as input8_9_2_,
gonogo3_.input_file_token as input1_6_0_,
gonogo3_.go_nogo_ind as go2_6_0_,
inputfile1_.input_file_name as input1_3_1_,
inputfile1_.src_code as src2_3_1_,
inputfile1_.process_cat_code as process3_3_1_
FROM input_file_log this_
left outer join go_nogo gonogo3_ on this_.input_file_token=gonogo3_.input_file_token
inner join input_file inputfile1_ on this_.input_file_name=inputfile1_.input_file_name
WHERE this_.file_creation_date > :p0 and
this_.file_creation_time > :p1 and
inputfile1_.input_file_name = :p2
ORDER BY this_.input_file_token desc;
:p0 = '20100401',
:p1 = '15:15:27',
:p2 = 'LMCONV_JR'
实际上,该查询正是我所期望的,只是它实际上并没有给我想要的东西(过去两周的所有行),因为在数据库中它正在执行大于使用 CHAR
而不是 DATE
的比较。我不知道如何让查询将 CHAR
值转换为查询中的 DATE
而不执行 CreateSQLQuery(),这是我想避免的。有人知道该怎么做吗?
更新: 我一直在尝试使用 Projections.SqlFunction()
或公式来完成此任务,但到目前为止没有任何效果。这是我使用 SqlFunction()
的代码,但我得到一个 NHibernate.QueryException : property does not map to a single columns: FileCreationDateTime
错误:
DateTime twoWeeksAgo = DateTime.Now.AddDays(-14);
ICriteria criteria =
Session.CreateCriteria<InputFileLog>()
.Add(Restrictions.Gt(Projections.SqlFunction("to_date", NHibernateUtil.DateTime, Projections.Property(MembersOf<InputFileLog>.GetName(x => x.FileCreationDateTime))), twoWeeksAgo))
//.Add(Expression.Gt(MembersOf<InputFileLog>.GetName(x => x.FileCreationDateTime), DateTime.Now.AddDays(-14)))
.AddOrder(Order.Desc(Projections.Id()))
.CreateCriteria(typeof(InputFile).Name)
.Add(Expression.Eq(MembersOf<InputFile>.GetName(x => x.Id), inputFileName));
我确信我'我在这里做了一些错误的事情,但它仍然不喜欢它,因为 FileCreationDateTime
使用自定义 ICompositeUserType
它将 .NET DateTime
属性分成两个Oracle SQL CHAR
列(请参阅此 StackOverflow 问题了解详细信息)。
I have an answered StackOverflow question about how to combine to legacy CHAR
database date and time fields into one .NET DateTime
property in my POCO
here (thanks much Berryl!). Now i am trying to get a custom ICritera query to work against that very DateTime
property to no avail. here's my query:
ICriteria criteria =
Session.CreateCriteria<InputFileLog>()
.Add(Expression.Gt(MembersOf<InputFileLog>.GetName(x => x.FileCreationDateTime), DateTime.Now.AddDays(-14)))
.AddOrder(Order.Desc(Projections.Id()))
.CreateCriteria(typeof(InputFile).Name)
.Add(Expression.Eq(MembersOf<InputFile>.GetName(x => x.Id), inputFileName));
IList<InputFileLog> list = criteria.List<InputFileLog>();
And here's the query it's generating:
SELECT this_.input_file_token as input1_9_2_,
this_.file_creation_date as file2_9_2_,
this_.file_creation_time as file3_9_2_,
this_.approval_ind as approval4_9_2_,
this_.file_id as file5_9_2_,
this_.process_name as process6_9_2_,
this_.process_status as process7_9_2_,
this_.input_file_name as input8_9_2_,
gonogo3_.input_file_token as input1_6_0_,
gonogo3_.go_nogo_ind as go2_6_0_,
inputfile1_.input_file_name as input1_3_1_,
inputfile1_.src_code as src2_3_1_,
inputfile1_.process_cat_code as process3_3_1_
FROM input_file_log this_
left outer join go_nogo gonogo3_ on this_.input_file_token=gonogo3_.input_file_token
inner join input_file inputfile1_ on this_.input_file_name=inputfile1_.input_file_name
WHERE this_.file_creation_date > :p0 and
this_.file_creation_time > :p1 and
inputfile1_.input_file_name = :p2
ORDER BY this_.input_file_token desc;
:p0 = '20100401',
:p1 = '15:15:27',
:p2 = 'LMCONV_JR'
The query is exactly what i would expect, actually, except it doesn't actually give me what i want (all the rows in the last 2 weeks) because in the DB it's doing a greater than comparison using CHAR
s instead of DATE
s. I have no idea how to get the query to convert the CHAR
values into a DATE
in the query without doing a CreateSQLQuery(), which I would like to avoid. Anyone know how to do this?
UPDATE:
I've been looking into trying to use Projections.SqlFunction()
or formulas to accomplish this, but to no avail so far. Here's the code i have using SqlFunction()
, but i get an NHibernate.QueryException : property does not map to a single column: FileCreationDateTime
error:
DateTime twoWeeksAgo = DateTime.Now.AddDays(-14);
ICriteria criteria =
Session.CreateCriteria<InputFileLog>()
.Add(Restrictions.Gt(Projections.SqlFunction("to_date", NHibernateUtil.DateTime, Projections.Property(MembersOf<InputFileLog>.GetName(x => x.FileCreationDateTime))), twoWeeksAgo))
//.Add(Expression.Gt(MembersOf<InputFileLog>.GetName(x => x.FileCreationDateTime), DateTime.Now.AddDays(-14)))
.AddOrder(Order.Desc(Projections.Id()))
.CreateCriteria(typeof(InputFile).Name)
.Add(Expression.Eq(MembersOf<InputFile>.GetName(x => x.Id), inputFileName));
I'm sure i'm doing something wrong here and it doesn't like it still anyway because FileCreationDateTime
uses a custom ICompositeUserType
which splits the .NET DateTime
property into two Oracle SQL CHAR
columns (see this StackOverflow question for details).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我终于弄清楚了!这是代码(出于某种原因,StackOverflow 将第一个代码片段中的一些方法名称设置为类型的语法颜色):
这是我用来创建
SQLProjections
和的方法SQLFunctions
。我将它们放入我的ICompositeUserType
(DefaultStringFileCreationDateTime
) 中,用于FileCreationDateTime
属性上的自定义类型映射。我已经在使用
consts
DatabaseFieldNames
struct
来实现PropertyNames
成员,因此我能够重用这些硬体我也需要的Projections
的编码列名称。这是
Projection
实用程序类,其中包含通用to_date
方法:最后,这是 NHibernate 生成的 Oracle SQL:
不敢相信我得到了这个!我想我肯定必须求助于
ISQLQuery
!I finally figure this out! here's the code (for some reason StackOverflow is making some of the methods names in the this first code snippet the syntax color of a type):
And here's the methods i used to create the
SQLProjections
andSQLFunctions
. i put them in myICompositeUserType
(DefaultStringFileCreationDateTime
) that i used for the custom type mapping on theFileCreationDateTime
property.I was already using the
consts
DatabaseFieldNames
struct
for thePropertyNames
member implementation, so I was able to reuse these hard-coded column names for theProjections
i needed as well.Here's the
Projection
utility class where the genericto_date
methods live:Finally, here's the Oracle SQL that NHibernate generates:
can't believe i got this one! i thought i was going to have to resort to an
ISQLQuery
for sure!