簡體   English   中英

NHibernate映射域的“擴展屬性”?

[英]NHibernate mapping domain “extension properties”?

我想“擴展”我的域類,而不必向域類本身添加數據。 考慮我有以下課程:

public class Person
{
public virtual int Id { get; private set; }
public virtual string Name { get; set; }
}

我在數據庫中有下表:

tblPersons
---------------
Id integer 
Name varchar(50)
CreatedBy varchar(50)
CreatedDate datetime

因此,我不想在域類中添加“ CreatedBy”和“ CreatedDate”,因為這與實際域本身無關...

每當我加載實體時是否有可能獲取此數據? 我想這樣使用它:

Person person = session.Load<Person>(1);

person.CreatedBy(); <-- CreatedBy is an Extension function
person.CreatedDate(); <-- CreatedDate is an Extension function

誰能指出我朝着哪個方向去實現這一目標?

我考慮過以下可能性:

  • 實現一個自定義的ProxyFactory,在其中注入自定義的“接口”(例如IUpdateable),但是NHibernate似乎並不能始終如一地創建代理,有時會加載我的“代理類”類,有時會加載“普通類” :

     Person person = session.Load<Person>(2); //this will load my Proxy class of Person just fine Address address = person.Address; //Somehow this doesn't load a Proxy for Address, but instead loads it normally - seems like it's evaluating "ImmediateLoad", which doesn't load proxies, due to lazy loading... not sure how to make this behave as I want. 
  • 使用自定義的PropertyAccessor。 我已經閱讀了一些有關此內容的信息-但看來我實際上必須將其映射到域類上退出的屬性...這樣就行不通了,對吧?

  • 就像NHibernate在創建Proxy類時向運行時“注入”代碼一樣-也許我可以做同樣的事情,但是將“接口”注入原始的Person類嗎?

您可以使用基類或組件映射輕松完成此操作。 我不會為此目的使用擴展方法。 我使用基類:

public abstract class Auditable : IAuditable
{
    public virtual string CreatedBy { get; set; }
    public virtual DateTime CreatedDate { get; set; }
}

public class Person : Auditable {}

流利的映射:

public class AuditableClassMap<T> : ClassMap<T> where T: IAuditable
{
    public AuditableClassMap()
    {
        Map(x => x.CreatedBy);
        Map(x => x.CreatedDate);
    }
}

public class PersonMap : AuditableClassMap<Person> {}

如果您堅持將審計屬性排除在類之外,則可以將審計屬性映射為一個組件。

這是一個主意。 我從未實現過此功能,因此請在測試之前先加一點鹽。

創建一個不同的類來封裝Person - PersonCreation或其他內容的審核數據。

給它一個標識符,一個創建日期和一個創建者屬性,以及一個Person ID的屬性(我認為實際上不需要引用Person ,除非標識符是非公開的,在這種情況下,您可能需要一個WeakReference所以您不要在應用程序的生命周期內將每個Person實例都保留在內存中)。

您需要為NHibernate創建一個映射,以從Person表中獲取PersonCreation對象。

從這里,您可以簡單地讓擴展方法在調用時獲取數據。 根據您的使用情況,這可能合理,也可能不合理。 您每次都必須創建一個新會話或同步靜態會話。

要么…

在包含您的CreatedBy()CreatedDate()擴展方法的static類中,創建一個靜態IDictionary<int, PersonCreation>來保存每個Person的詳細信息。 由於創建數據可能是不可變的,因此我們真的不必擔心它會過時。

您將要使用您的Person查詢對PersonCreation查詢進行批處理。 例如,您可以執行以下操作:

var creation = session.CreateCriteria<PersonCreation>()
    .Add(Restrictions.Eq("PersonId", 1))
    .Future<PersonCreation>();

var person = session.CreateCriteria<Person>()
    .Add(Restrictions.IdEq(1))
    .UniqueResult<Person>();

通過調用Future<T>() ,您告訴NHibernate在會話已經進入數據庫之前不要執行該查詢。

獲得結果后,您可以獲取第一個創建結果並將其添加到字典中(以便擴展方法可以訪問它),然后返回此人。

當您調用person.CreatedDate() ,該方法可以使用傳遞的Person參數的ID或Person本身從字典中提取數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM