2010-09-01 67 views
1

我有我想作爲組分映射到包含它的任何表的類:功能NHibernate - 映射的實體作爲不同類型的

public class Time 
{ 
    public int Hours { get; set; } 
    public int Minutes { get; set; } 
    public int Seconds { get; set; } 
} 

我想這個類存儲爲bigint在數據庫中 - 與存儲TimeSpan的方式相同,但我的班級有完全不同的行爲,所以我決定創建自己的班級。

我正在使用FLH的automapper並將此類設置爲組件(其他類有Time作爲屬性)。據我得爲創建覆蓋,但我不知道如何去了解它映射:

我給它一個嘗試這種方式:

public class TimeMappingOverride : IAutoMappingOverride<Time> 
{ 
    public void Override(AutoMapping<Time> mapping) 
    { 
     mapping.Map(x => x.ToTimeSpan()); 
     mapping.IgnoreProperty(x => x.Hours); 
     mapping.IgnoreProperty(x => x.Minutes); 
     mapping.IgnoreProperty(x => x.Seconds); 
    } 
} 

但得到這個錯誤:

Unable to cast object of type 'System.Linq.Expressions.UnaryExpression' to type 'System.Linq.Expressions.MethodCallExpression'.

我該怎麼處理?

回答

2

詳細信息可以在這裏找到:http://wiki.fluentnhibernate.org/Fluent_mapping#Components

但首先,你不能映射的方法。

假設你改變ToTimeSpan()一個屬性AsTimeSpan,有兩種方法可以做到這一點,只有更努力,其中會爲你工作,因爲你正在使用自動映射:

  1. 創建ComponentMap<Time> - 做一次,您現有的映射將會正常工作。這與自動映射不兼容。
  2. 聲明組件映射內聯:
mapping.Component(x => x.AsTimeSpan, component => { 
    component.Map(Hours); 
    component.Map(Minutes); 
    component.Map(Seconds); 
    }); 

你每次都這樣做,雖然。

當然,這並沒有解決「我想用來存儲這個類作爲bigint ......」

你是說你要堅持它作爲唯一秒鐘?如果是這樣,在頂部劃傷一切,再次你有兩種選擇:

  1. 實現NHibernate的IUserType(啊)
  2. 創建存儲的值只有幾秒鐘的私人財產或領域,只有這件事絲NHibernate的。公共財產的獲得者和制定者將必須轉換成秒數。
+0

我希望可能有某種方式迫使NHibernate將這個類映射爲'TimeSpan'。該類本身具有隱式運算符來自'TimeSpan'。 – 2010-09-01 16:23:08

+0

@David你可以像我之前描述的那樣完成相同的操作 - 創建一個'TimeSpan'類型的私有成員並讓NHibernate獲取/設置它。給定隱式運算符,您的公共屬性和方法可以獲取/設置此私有成員的值。 – Jay 2010-09-01 16:50:33

0

我個人還沒有使用AutoMappings,但我的建議是看看NHibernate的IUserType改變如何保持一個類型。我相信這是定義自定義映射Time <-> bigint的更簡潔的方式。

讀取上面的代碼Map(x => x.ToTimeSpan())將不起作用,因爲您無法將應用程序到數據庫轉換代碼嵌入到映射中。即使這是可能的,聲明也會錯過從數據庫到應用程序的轉換。另一方面,IUserType可以在NullSafeGetNullSafeSet方法中進行自定義轉換。組件