2015-01-13 19 views
3

我有一堆C#類,它們從一個抽象基類繼承了許多屬性。所有類型都使用Fluent NHibernate映射到數據庫模型,所有屬性定義都使用自動獲取器和設置器(標準「get; set;」語法)。我最近發現需要爲其中一個派生類型的基類型屬性的訪問器方法之一提供特定的實現。因此,我創建顯式支持字段的基礎類屬性:用Fluent NHibernate覆蓋C#屬性存取方法的基本行爲

public abstract class BaseEntity : IBaseEntity 
{ 
    protected bool active_field; 

    ... 

    public virtual bool active { get { return active_field; } set { active_field = value; } } 

    ... 

} 

然後定義的特定的吸氣劑邏輯在派生類型定義中的「活躍」屬性:

public override bool active 
    { 
     get { return active_field && (this.Expiration == null || this.Expiration < DateTime.Now); } 
     set { active_field = value; } 
    } 

當我火了該項目雖然NHibernate拋出一個異常:

在FluentNHibernate.dll中發生類型'System.InvalidOperationException'的異常,但未在用戶代碼中處理。 附加信息:嘗試添加屬性'活動'時已添加。

我猜這與NHibernate需要提供它自己的屬性定義覆蓋(因此爲什麼它需要屬性被聲明爲虛擬的第一位),但我並不是全部NHibernate的精明。既然如此,我很樂意提供任何其他細節,但不知道還有什麼相關的。有沒有明顯的原因,爲什麼這不起作用?如果是這樣,是否有一個簡單的解決方法?

+0

如果您爲另一個非公有虛擬屬性創建'active'非虛擬包裝怎麼辦? 'NHibernate'會填充非公有財產嗎? –

+0

所以你有'ClassMap '顯式映射或使用Automapping?此外,覆蓋是有缺陷的,因爲即使active_field值沒有改變,活動值也會改變。更好地區分'IsActivated' /'IsEnabled'(持續)和'IsActive' – Firo

+0

這是使用自動映射。我不確定你在後半部分的含義。所有派生自BaseEntity的類型都可以通過將活動位設置爲0來「軟刪除」。最近我添加了一些BaseEntity類型,它們有過期日期,並且我有一個完整的代碼庫,它已經明確地檢查了活動字段在檢查數據時。當然,我的目標是能夠查看一個BaseEntity類型,如果過期已過,則將過期屬性視爲不活動,而無需在已檢查活動字段的位置手動檢查它。那是不好的形式? –

回答

0

我並不完全確定你的問題的根源,但是,試圖回答你的問題:

  1. 的NHibernate需要的所有屬性,因爲它創建一個代理,是虛擬的,允許再偷懶裝你的實體類型(這是你的類的擴展)。它需要它們是虛擬的,因此它可以覆蓋它們並在其中注入新的行爲(用數據庫值填充它們);
  2. 您可以映射非公共屬性和字段,但您必須明確地執行此操作,請遵循有關如何使用FluentNHibernate執行此操作的示例。

映射一個私有屬性或字段:

public class EntityMap : ClassMap<Entity> 
{ 
    Id(e => e.Id).GeneratedBy.Identity(); 
    Map(Reveal.Member<Entity>("PrivatePropertyName")); 
} 

現在的建議來嘗試解決問題:您可以隱藏在使用關鍵字的擴展類的屬性(屬性仍然需要爲虛擬)。

public virtual new bool active 
{ 
    get { return active_field && (this.Expiration == null || this.Expiration < DateTime.Now); } 
    set { active_field = value; } 
}