NHibernate问题与指定的字符串ID和不同的案例字符

我在NHibernate上保存一个带有指定字符串Id的实体时遇到问题……我试着用一个例子来解释这个问题。

好吧,如果我执行这些语句,假设在ID为“AAA”的数据库上有一个实体

ENTITYTYPE entity = Session.Get("AAA"); ENTITYTYPE newentity = new ENTITYTYPE() { Id = "aaa" }; Session.Delete(entity); Session.Save(newentity); Session.Flush(); 

在Flush上,NHibernate使用以下消息引发exception:“无法使数据库状态与会话同步”/“违反PRIMARY KEY”

它似乎与Case Sensitive ID有问题,如果我在“newentity”的Id上使用“AAA”然后它可以工作,但在我的情况下并不那么容易,我要找到另一种解决方案。

如何避免这种exception? 你能帮助我吗?

我不知道它是否适用但你用这样的东西控制它:

 public override bool Equals(object obj) { T other = obj as T; if (other == null) return false; // handle the case of comparing two NEW objects bool otherIsTransient = Equals(other.Id, Guid.Empty); bool thisIsTransient = Equals(Id, Guid.Empty); if (otherIsTransient && thisIsTransient) return ReferenceEquals(other, this); return other.Id.ToUpper().Equals(Id.ToUpper()); } 

在比较实体时使用ToUpper()或ToLower()方法,或者可以使用String.Compare(stringA,strngB,StringComparison.OrdinalIgnoreCase)。

如果您想要更多控制权,如果这是您的目标,您可以按照此处的说明创建自定义ID生成器:

http://nhibernate.info/doc/howto/various/creating-a-custom-id-generator-for-nhibernate.html

更新

你尝试过创建自定义GetIgnoreCase(…)吗?

我认为也可以通过loader标签覆盖实体映射文件中默认生成的SELECT方法,如下例所示:

  ...      

您可以尝试修改返回大写ID的select语句。

更新

经过进一步的调查后,我认为解决问题的方法可以是使用拦截器!

在这里阅读:

http://knol.google.com/k/fabio-maulo/nhibernate-chapter-11-interceptors-and/1nr4enxv3dpeq/14#

更多文档:

http://blog.scooletz.com/2011/02/22/nhibernate-interceptor-magic-tricks-pt-5/

像这样的东西:

  public class TestInterceptor : EmptyInterceptor, IInterceptor { private readonly IInterceptor innerInterceptor; public TestInterceptor(IInterceptor innerInterceptor) { this.innerInterceptor = this.innerInterceptor ?? new EmptyInterceptor(); } public override object GetEntity(string entityName, object id) { if (id is string) id = id.ToString().ToUpper(); return this.innerInterceptor.GetEntity(entityName, id); } } 

并像这样流利地注册它:

 return Fluently.Configure() ... .ExposeConfiguration(c =>{c.Interceptor = new TestInterceptor(c.Interceptor ?? new EmptyInterceptor());}) ... .BuildConfiguration();