- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
首先让我为这篇文章的长度道歉,虽然它主要是代码,所以我希望大家多多包涵!
我有一个处理遗留数据库的场景,我需要使用 NHibernate 3.2 编写一个 IUserType 来获取一个 2 个字符的“状态”字段并从中返回一个 bool 值。状态字段可以包含 3 个可能的值:
* 'DI' // 'Disabled', return false
* ' ' // blank or NULL, return true
* NULL
CREATE TABLE [dbo].[Client](
[clnID] [int] IDENTITY(1,1) NOT NULL,
[clnStatus] [char](2) NULL,
[clnComment] [varchar](250) NULL,
[clnDescription] [varchar](150) NULL,
[Version] [int] NOT NULL
)
public class ClientMapping : CoreEntityMapping<Client>
{
public ClientMapping()
{
SchemaAction.All().Table("Client");
LazyLoad();
Id(x => x.Id, "clnId").GeneratedBy.Identity();
Version(x => x.Version).Column("Version").Generated.Never().UnsavedValue("0").Not.Nullable();
OptimisticLock.Version();
Map(x => x.Comment, "clnComment").Length(250).Nullable();
Map(x => x.Description, "clnDescription").Length(250).Nullable();
Map(x => x.IsActive, "clnStatus").Nullable().CustomType<StatusToBoolType>();
}
}
public class StatusToBoolType : IUserType
{
public bool IsMutable { get { return false; } }
public Type ReturnedType { get { return typeof(bool); } }
public SqlType[] SqlTypes { get { return new[] { NHibernateUtil.String.SqlType }; } }
public object DeepCopy(object value)
{
return value;
}
public object Replace(object original, object target, object owner)
{
return original;
}
public object Assemble(object cached, object owner)
{
return cached;
}
public object Disassemble(object value)
{
return value;
}
public new bool Equals(object x, object y)
{
if (ReferenceEquals(x, y)) return true;
if (x == null || y == null) return false;
return x.Equals(y);
}
public int GetHashCode(object x)
{
return x == null ? typeof(bool).GetHashCode() + 473 : x.GetHashCode();
}
public object NullSafeGet(IDataReader rs, string[] names, object owner)
{
var obj = NHibernateUtil.String.NullSafeGet(rs, names[0]);
if (obj == null) return true;
var status = (string)obj;
if (status == " ") return true;
if (status == "DI") return false;
throw new Exception(string.Format("Expected data to be either empty or 'DI' but was '{0}'.", status));
}
public void NullSafeSet(IDbCommand cmd, object value, int index)
{
var parameter = ((IDataParameter) cmd.Parameters[index]);
var active = value == null || (bool) value;
if (active)
parameter.Value = " ";
else
parameter.Value = "DI";
}
}
[TestMethod]
public void GetAllActiveClientsTest()
{
//ACT
var count = Session.QueryOver<Client>()
.Where(x => x.IsActive)
.SelectList(l => l.SelectCount(x => x.Id))
.FutureValue<int>().Value;
//ASSERT
Assert.AreNotEqual(0, count);
Assert.AreEqual(1721, count);
}
SELECT count(this_.clnID) as y0_ FROM Client this_ WHERE this_.clnstatus = @p0;
/* @p0 = ' ' [Type: String (0)] */
SELECT count(this_.clnID) as y0_ FROM Client this_ WHERE (this_.clnstatus = @p0 <b> OR this_.clnstatus IS NULL);</b>
...
public void NullSafeSet(IDbCommand cmd, object value, int index)
{
var parameter = ((IDataParameter) cmd.Parameters[index]);
var active = value == null || (bool) value;
if (active)
{
parameter.Value = " ";
if (cmd.CommandText.ToUpper().StartsWith("SELECT") == false) return;
var paramindex = cmd.CommandText.IndexOf(parameter.ParameterName);
if (paramindex > 0)
{
// Purpose: change [columnName] = @p0 ==> ([columnName] = @p0 OR [columnName] IS NULL)
paramindex += parameter.ParameterName.Length;
var before = cmd.CommandText.Substring(0, paramindex);
var after = cmd.CommandText.Substring(paramindex);
//look at the text before the '= @p0' and find the column name...
var columnSection = before.Split(new[] {"= " + parameter.ParameterName}, StringSplitOptions.RemoveEmptyEntries).Reverse().First();
var column = columnSection.Substring(columnSection.Trim().LastIndexOf(' ')).Replace("(", "");
var myCommand = string.Format("({0} = {1} OR {0} IS NULL)", column.Trim(), parameter.ParameterName);
paramindex -= (parameter.ParameterName.Length + column.Length + 1);
var orig = before.Substring(0, paramindex);
cmd.CommandText = orig + myCommand + after;
}
}
else
parameter.Value = "DI";
}
最佳答案
解决了!
在我发布我的问题后,我回到了绘图板上,我想出了一个不需要在 IUserType 实现中破解生成的 SQL 的解决方案。事实上,这个解决方案根本不需要 IUserType!
这就是我所做的。
首先,我将 IsActive 列更改为使用公式来处理空值检查。这解决了我的 QueryOver 失败的问题,因为现在 NHibernate 每次处理 IsActive 属性时,它都会注入(inject)我的 sql 公式来处理 null。
这种方法的缺点是,在我输入公式后,我所有的保存测试都失败了。事实证明,公式属性实际上是只读属性。
所以为了解决这个问题,我向实体添加了一个 protected 属性来保存数据库中的状态值。
接下来,我更改了 IsActive 属性,将 protected 状态属性设置为“”或“DI”。最后,我将 FluentMapping 更改为将 protected Status 属性更改为 NHibernate,以便 NHibernate 可以跟踪它。现在 NHibernate 已经知道了 Status,它可以将它包含在它的 INSERT/UPDATE 语句中。
我将在下面包含我的解决方案,以防其他人感兴趣。
客户类
public class Client
{
...
protected virtual string Status { get; set; }
private bool _isActive;
public virtual bool IsActive
{
get { return _isActive; }
set
{
_isActive = value;
Status = (_isActive) ? " " : "DI";
}
}
}
public class ClientMapping : CoreEntityMapping<Client>
{
public ClientMapping()
{
....
Map(Reveal.Member<E>("Status"), colName).Length(2);
Map(x => x.IsActive).Formula("case when clnStatus is null then ' ' else clnStatus end");
}
}
关于IUserType 上的 NHibernate QueryOver,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8796879/
我一直在为初学者阅读 nhibernate 3.0 并阅读了一些常见错误(我犯了一些错误) 我想知道将一个或多个记录设为只读有哪些策略。现在我取回所有行并循环遍历它们,使它们通过 session.Re
我们有一个使用 NHibernate 的相当健壮的系统,我们正在从单个数据库服务器迁移到拥有两台服务器,一台用于管理,另一台用于我们面向公众的网站。这主要是为了让我们可以使用不会影响当前站点的工作流来
我在尝试构建一个时遇到以下错误 session 工厂: PersistenceTests.Can_Map_Orders_To_Database : Failed System.IndexOutOfRa
如果客户有很多订单附加到他们。您将如何使用 NHibernate 延迟加载订单列表。 是不是需要设置映射文件?任何帮助或示例都会很棒。 最佳答案 Chris 的建议是我会怎么做,但是如果您想在运行时执
我正在尝试使用 HQL 对一个简单的查询进行分页,并将总行数作为同一查询的一部分进行检索。 我的查询很简单... var members = UnitOfWork.CurrentSession.Cre
我有旧版数据库,存储的日期表示无日期为9999-21-31, 列Till_Date的类型为DateTime not-null="true"。 在应用程序中,我要构建持久化类,将no-date表示为nu
您可以指定命名空间和程序集以使用 HBM 文件顶部的类型: 您可以在同一个映射文件中使用来自多个程序集/命名空间的类型,如果可以,这样做的语法是什么? 最佳答案 您可以从 HBM 文件的顶部删除默认
如何强制 NHibernate 在多对多集合上执行 RIGHT 外连接或 INNER 连接而不是 LEFT 外连接? 我想这样做的原因是因为过滤应用于集合元素。使用左连接,您将获得与未过滤查询相同的返
我们开始在我的工作场所使用NHibernate,包括从映射生成模式。我们的DBA想要的一件事是主键和外键关系的名称一致。我已经能够设置FK约束名称,但是在的文档中看,它似乎不存在命名主键约束的方法。
我需要NHibernate来执行这样的查询: SELECT * FROM Users ORDER BY Func(FirstName, LastName) Standart NHibernate Or
假设在一个实体中有属性 id、用户名、年龄、地址。现在我只想要 id 和 username 并使用此代码。 投影可以从查询中返回实体列表以外的内容。 var proj = Projections.Pr
我花了很长时间,但我终于让 nHibernate 的 Hello World 工作了。在我做了“延迟加载”之后它起作用了。老实说,我无法告诉您为什么这一切都有效,但确实如此,现在我正在阅读您不需要延迟
假设您有两个类,Person 和 Address。 Person 有一个对 Address 的引用,如下所示: public class Person { public virtual Addre
我在 NHibernate 引用文档 中阅读第 10 章“只读实体”如下: http://nhibernate.info/doc/nh/en/index.html#readonly 但不幸的是我不知道
有谁知道 NHibernate 是否支持从存储过程返回输出参数?我在文档中进行了搜索,但无法真正找到任何可以确认的内容。 最佳答案 我面临同样的问题。 NHibernate 不允许您以这种方式使用存储
简而言之,什么工作得更快: SessionFactory 预编译 XML 配置,或 流畅的NHibernate提供 以编程方式配置? 最佳答案 我个人的经验是,Configuration 对象的构建(
我的域类具有如下所示的集合: private List _foos = new List(); public virtual ReadOnlyCollection Foos { get { retur
当我有一个带有一对多子集合的实体对象时,我需要查询一个特定的子对象,是否有我还没有想出的功能或一些巧妙的模式来避免 NHibernate获取整个子集合? 例子: class Parent {
在我的域中,员工和部门具有一对多的双向关系;为了让子员工同步这个,我有一个“内部”访问字段,用于部门中员工的集合(NHibernate 的 Iesi),否则它将是只读公共(public)的。像这样:
我有一个 nhibernate 自定义类型,我想用 Fluent NHibernate 映射它。 HBM 映射如下所示。 Services.Data.DateConventionTyp
我是一名优秀的程序员,十分优秀!