2010-05-20 109 views
6

我有一个使用Criteria的nHibernate查询,并且我试图在查询本身中将字符串转换为bool。我已经做了与铸造一个字符串为int相同,而且效果很好(以下简称“数据字段”属性为“1”作为一个字符串):使用nHibernate标准将字符串转换为bool标准

var result = Session 
    .CreateCriteria<Car>() 
    .Add(Restrictions.Eq((Projections.Cast(NHibernateUtil.Int32, 
    Projections.Property("DataField"), 1)) 
    .List<Car>(); 

tx.Commit(); 

但我试图做同样的布尔,但我没有得到期望的结果:

var result = Session 
    .CreateCriteria<Car>() 
    .Add(Restrictions.Eq((Projections.Cast(NHibernateUtil.bool, 
    Projections.Property("DataField"), true)) 
    .List<Car>(); 

tx.Commit(); 

“数据字段”是字符串“真”,但结果在一个空的列表,其中应包含与设置为“数据字段”属性字符串100个元素“真”。我尝试过使用字符串“true”和“1”,但结果仍然是一个空列表。

[编辑]

如下评论,我可以检查字符串“真”或“假”,但我会说这是不仅仅是一个布尔一个更具普遍性的问题。

请注意,这个想法是有某种键值表示的数据,其中的值可以是不同的数据类型。我需要值表来包含所有数据,因此将数据存储为字符串似乎是最干净的解决方案!

我已经能够使用上面的方法来存储int和double作为字符串,并在查询中强制转换,但我没有成功使用DateDime和Boolean的相同方法。

而对于DateTime,实际的DateTime对象是至关重要的。

如何将字符串转换为布尔值,并将字符串转换为DateTime在查询中工作?

感谢

+1

我不明白为什么不只是'Restrictions.Eq(“DataField”,“True”)' – 2010-05-20 20:27:14

+0

你是对的。对于布尔值,我可以轻松地进行字符串比较,但是对于DateTime,我有和bool相同的问题,并且将字符串强制转换为DateTime对象是至关重要的 – 2010-05-21 08:04:23

+0

为什么您将datetime字段映射为字符串? – 2010-05-21 13:44:22

回答

5

不幸的是,你要实现的目标是什么将是很难做到的,因为它违背了什么样的NHibernate和RDBMS中试图为你做粮食。通过使用无类型数据,您将避开使用RDBMs带来的许多收益。

没有完整的模式,我只能猜测。你怎么知道这个领域的正确类型是什么?我猜你有一个'type'列,指示该值是否为整数,布尔值,日期等。如果是这样,继续使用类型标识符列,并为每个数据类型加上单独的列。这并不比你在做什么复杂,因为对于每种数据类型已经有了单独的查询,并且你可以清楚地看到类型检查和索引的可能性。

如果要防止定义多个值的可能性(即多个类型列中的值),则可以在该表上创建一个约束来验证每个行仅为最多一个数据类型定义了一个值。 (您也可以验证指定类型的列是否为空,如果这适合您的情况。)

更改后,您可以让nHibernate管理不同的类型,并让它为您完成所有繁重的工作。 NHibernate的可以映射类hiearchies对表,所以你可以创建这样的实体:

public class AbstractProperty 
{ 
    // concrete name - persisted 
    public String Name { get; set; etc.. } 

    // owner property as well? 

    // abstract value provided by subclasses. This property is not persisted. 
    // used simply to provide polymorphic access to the value. 
    public abstract Object Value { get; set; } 
} 

public class DateProperty : AbstractProperty 
{ 
    // concrete date property 
    public Date date { get; set; etc.. } 

    // value delegates to date property 
    public Object value { get; set; } 
} 

有了这个计划,你必须与特定的数据类型,其中,例如,查询使用检索值的选项DateProperty实体明确返回DateProperty实例。您还可以编写可能返回多种类型的查询,其中静态类型为AbstractProperty。然后,您可以使用visitor pattern或AbstractProperty上的'is'检查来确定类型并将其转换为具体类型以获取该值。

一位nHibernate专家可能能够帮助您修复演员阵容,但从长远来看,我建议在您的数据库中使用真实的数据类型。它会在以后节省您的头痛。

+0

感谢您的好评。我会研究你的解决方案! – 2010-05-23 13:32:54

+1

这也是我所建议的;在hibernate中使用继承可以查询任何通用属性,但是您可以为每个类型提供一个表,并在模式中使用适当类型的列。 – RMorrisey 2010-05-28 18:40:11