在NHibernate中将空字符串映射为NULL

for*_*i23 2 nhibernate fluent-nhibernate

我有一个带有递归表的SQL Server DB:

MyTable:
 ID : string PrimaryKey
 Parent: string references MyTable - NOTNULL !!
Run Code Online (Sandbox Code Playgroud)

并使用Fluent NHibernate映射到

class MyTable
{
  public virtual string ID {get; set;}
  public virtual MyTable Parent {get; set;}
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,如果数据库中的Parent列为""(空字符串),则Parent应该在我的C#app中为null,反之亦然.不幸的是我无法更改列类型以接受NULL!

我试图使用IEmptyInterceptor,但我没有让它工作.

提前谢谢,forki

Ale*_*roß 5

您需要为主键列提供IUserType,它会执行特殊的NULL值处理.

public MyTableMap()
{
    Id(x => x.EntryNo)
        // Since the PK is a string, it must be assigned by the application.
        .GeneratedBy.Assigned()
        .SetAttribute("type", typeof(SpecialNullValueStringType).AssemblyQualifiedName);

    References(x => x.Parent);
}

public class SpecialNullValueStringType : IUserType
{
    #region IUserType Members
    public bool IsMutable
    {
        get { return false; }
    }

    public Type ReturnedType
    {
        get { return typeof(string); }
    }

    public SqlType[] SqlTypes
    {
        get { return new[] { NHibernateUtil.String.SqlType }; }
    }

    public object NullSafeGet(IDataReader rs, string[] names, object owner)
    {
        var obj = NHibernateUtil.String.NullSafeGet(rs, names[0]);

        if (obj == null)
        {
            return null;
        }

        var value = (string) obj;
        if (String.IsNullOrEmpty(value))
        {
            return null;
        }

        return value;
    }

    public void NullSafeSet(IDbCommand cmd, object value, int index)
    {
        if (value == null)
        {
            ((IDataParameter) cmd.Parameters[index]).Value = String.Empty;
        }
        else
        {
            ((IDataParameter) cmd.Parameters[index]).Value = value;
        }
    }

    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(string).GetHashCode() + 473 : x.GetHashCode();
    }
    #endregion
}
Run Code Online (Sandbox Code Playgroud)