我有一个使用Criteria的nHibernate查询,我试图在查询本身中将一个字符串转换为bool。我已经将字符串转换为int,并且效果很好(“DataField”属性为“1”作为字符串):
var result = Session
.CreateCriteria<Car>()
.Add(Restrictions.Eq((Projections.Cast(NHibernateUtil.Int32,
Projections.Property("DataField"), 1))
.List<Car>();
tx.Commit();
但我试图用bool做同样的事情,但我没有得到预期的结果:
var result = Session
.CreateCriteria<Car>()
.Add(Restrictions.Eq((Projections.Cast(NHibernateUtil.bool,
Projections.Property("DataField"), true))
.List<Car>();
tx.Commit();
“DataField”是字符串“True”,但结果为空列表,其中应包含100个元素,其中“DataField”属性字符串设置为“True”。我尝试使用字符串“true”和“1”,但结果仍然是一个空列表。
[编辑]
如下所述,我可以检查字符串“True”或“False”,但我想说这是一个比布尔值更普遍的问题。
请注意,这个想法是对数据进行某种键值表示,其中值可以是不同的数据类型。我需要值表来包含所有数据,因此将数据存储为字符串似乎是最干净的解决方案!
我已经能够使用上面的方法将int和double存储为字符串,并将其存储到查询中的强制转换,但我没有成功使用相同的方法进行DateDime和Boolean。
对于DateTime,拥有实际的DateTime对象至关重要。
如何将从字符串转换为bool,将字符串转换为DateTime在查询中工作?
由于
答案 0 :(得分:5)
不幸的是,你想要实现的目标很难做到,因为它违背了nHibernate和RDBM试图为你做的事情。通过使用无类型数据,您将回避使用RDBM为您提供的大量收益。
如果没有完整的架构,我只能猜测。你怎么知道这个领域的正确类型是什么?我猜你有一个'type'列,指示该值是否为整数,布尔值,日期等。如果这样做,请继续使用类型标识符列,并为每种数据类型添加单独的列。这并不比你正在做的复杂,因为每种数据类型都有单独的查询,你可以获得清晰度,类型检查和索引的可能性。
如果要防止定义多个值的可能性(即多个类型列中的值),可以在表上创建一个约束,以验证每行只定义最多一种数据类型的值。 (如果适合您的情况,您也可以验证指定类型的列是否为空。)
有意义的是,你可以让nHibernate管理不同的类型,并让它为你做所有繁重的工作。 nHibernate可以将类层次结构映射到表,因此您可以创建如下的实体:
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
。然后,您可以使用AbstractProperty上的visitor pattern或'is'检查来确定类型并转换为具体类型以获取值。
nHibernate专家可能能够帮助您修复演员表,但从长远来看,我建议您在数据库中使用真实的数据类型。它会在以后为您节省麻烦。