2011-01-23 43 views
4

我得到了一个遗留数据库,其中在FK列中使用了0值表示没有指定关系。nhibernate,外键列中的0

这不是我可以用一个微不足道的方式改变的东西。是否有可能告诉NHibernate在指定的列中将0视为null?

编辑

我知道not-found,但我只是想忽略那些0

+0

你可以添加一个关系无线FK引用表中的PK是0吗? – Mark 2011-01-23 22:20:50

+0

不,我不能。如果没有关系,所有代码都希望模型包含null。 – jgauffin 2011-01-24 05:50:05

回答

0

该解决方案为我们伟大的工作:http://nhibernate.info/blog/2011/01/28/how-to-use-0-instead-of-null-for-foreign-keys.html

简而言之:

添加以下类:

public class NullableTuplizer : PocoEntityTuplizer 
{ 
    public NullableTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) 
     : base(entityMetamodel, mappedEntity) 
    { 
    } 

    public override object[] GetPropertyValuesToInsert(
     object entity, IDictionary mergeMap, ISessionImplementor session) 
    { 
     object[] values = base.GetPropertyValuesToInsert(entity, mergeMap, session); 
     //dirty hack 1 
     for (int i = 0; i < values.Length; i++) 
     { 
      if (values[i ] == null && typeof (IEntity).IsAssignableFrom(getters[i ].ReturnType)) 
      { 
       values[i ] = ProxyFactory.GetProxy(0, null); 
      } 
     } 
     return values; 
    } 

    public override object[] GetPropertyValues(object entity) 
    { 
     object[] values = base.GetPropertyValues(entity); 
     //dirty hack 2 
     for (int i = 0; i < values.Length; i++) 
     { 
      if (values[i ] == null && typeof (IEntity).IsAssignableFrom(getters[i ].ReturnType)) 
      { 
       values[i ] = ProxyFactory.GetProxy(0, null); 
      } 
     } 
     return values; 
    } 


    public override void SetPropertyValues(object entity, object[] values) 
    { 
     //dirty hack 3. 
     for (int i = 0; i < values.Length; i++) 
     { 
      if (typeof (IEntity).IsAssignableFrom(getters[i ].ReturnType) 
       && ((IEntity) values[i ]).Id == 0) 
      { 
       values[i ] = null; 
      } 
     } 
     base.SetPropertyValues(entity, values); 
    } 
} 

然后将其注册为每一个相关的映射:

foreach (var persistentClass in configuration.ClassMappings) 
{ 
    persistentClass.AddTuplizer(EntityMode.Poco, typeof(NullableTuplizer).AssemblyQualifiedName); 
}