[英]Making NHibernate “translate” C# POCO Guid property with value of System.Guid.Empty to be saved as NULL for the Database uniqueidentifier field?
我們的辦公室團隊正在研究使用.NET Framework 4和NHibernate 3.3.1的ASP.NET項目。
我有一個名為AllResourcesInfo的POCO域類(該類最終映射到數據庫中的Resource表,該數據庫內部連接到其他一些表,但是為了簡單起見,我們只說AllResourcesInfo映射到Resource表)。
我也有一個稱為Department的POCO域類(該類最終映射到數據庫中的Department表)
AllResourcesInfo可能與部門有多對一關系。
如果AllResourcesInfo的實例屬於部門,則AllResourcesInfo.DepartmentDatabaseID具有在Department實體中的有效DepartmentDatabaseID。
但是,如果AllResourcesInfo的實例不屬於某個部門,則AllResourcesInfo.DepartmentDatabaseID在數據庫中的值為NULL。 數據庫。
當我使用NHibernate從AllResourcesInfo表中檢索(基本上是NHibernate對數據庫進行讀取)值時,NHibernate將使用00000000-0000-0000-0000-0000-000000000000值(即System.Guid)填充AllResourcesInfo.DepartmentDatabaseID的C#POCO屬性。 .Empty值)如果AllResourcesInfo不屬於部門
但是,當我使用NHibernate Session保存不屬於任何部門的全新的AllResourcesInfo的C#POCO實例時,我用00000000-0000-0000-0000-0000-000000000000的值(即系統)填充AllResourcesInfo.DepartmentDatabaseID的POCO屬性。 .Guid.Empty值),但數據庫顯然會引發錯誤,因為在數據庫的Department表中顯然不存在Guid值00000000-0000-0000-0000-000000000000。
總而言之,當我們希望NHibernate Session Save將uniqueidentifier字段值保留為null時,它無法將數據庫中的uniqueidentifier字段保存(或保留為NULL)。
有人可以告訴我如何確保NHibernate“轉換”具有System.Guid.Empty值的C#POCO Guid屬性,以便將數據庫uniqueidentifier字段值保存(或保留為NULL)嗎?
Guid不能為null。 您可以將類型更改為Nullable<Guid>
或Guid?
簡而言之,允許為空。
您需要實現NHibernate的IUserType。
它應該像這樣:
using NHibernate.SqlTypes;
using NHibernate.UserTypes;
[Serializable] //to allow NH configuration serialization
public class GuidTypeConverter : IUserType
{
SqlType[] sqlTypes;
public GuidTypeConverter()
{
sqlTypes = new[] { SqlTypeFactory.GetSqlType(DbType.Guid, 0, 0) };
}
public SqlType[] SqlTypes
{
get { return sqlTypes; }
}
public Type ReturnedType
{
get { return typeof(Guid); }
}
public object NullSafeGet(IDataReader rs, string[] names, object owner)
{
if (rs[names[0]] == DBNull.Value)
{
return Guid.Empty;
}
return (Guid) rs[names[0]];
}
public void NullSafeSet(IDbCommand cmd, object value, int index)
{
var param = (IDataParameter) cmd.Parameters[index];
param.DbType = sqlTypes[0].DbType;
var guid = (Guid) value;
if (guid != Guid.Empty)
{
param.Value = guid;
}
else
{
param.Value = DBNull.Value;
}
}
public bool IsMutable
{
//guid is struct so it's not mutable
get { return false; }
}
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)
{
return x != null && x.Equals(y);
}
public int GetHashCode(object x)
{
return x.GetHashCode();
}
}
(請注意,我還沒有測試過,這里有演員表-可能需要一些調整)
在映射中,您可以指定:
<property name="GuidProperty" column="guidColumn" type="GuidTypeConverterNamespace.GuidTypeConverter, GuidTypeConverterAssemblyName" />
您要做的是在數據庫中的Guid(不可為空的Guid)和GUID之間創建映射。 這是NHibernate中IUserType接口的目的。 您將需要一個自定義的GuidUserType類來執行翻譯,然后在映射定義中引用它(hbxml,fluent等)。 有關完整說明,請參見http://blog.miraclespain.com/archive/2008/Mar-18.html 。
在Department對象的主鍵的映射中,應該有一個名為unsaved-value的屬性。 將其設置為Guid.Empty的值,一切都會好的。
以下是使用原始hbm映射的示例:
<id name="DepartmentId" type="Guid" unsaved-value="00000000-0000-0000-0000-000000000000">
<generator class="guid" />
</id>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.