2009-10-07 63 views
5

我是NHibernate(和ORMS)的新手,試圖去處理它提供的各種不同選項。作爲參考,我將Fluent NHibernate與單獨的業務對象一起使用,而這些業務對象又將DTO完全用於數據訪問。我的應用程序架構必須同時支持Windows和Web「前端」。構建NHibernate DTO的最佳方法

我的困惑是一種普遍的方法,因爲似乎有這麼多的選擇。我的DTO看起來像下面的示例。每個DTO都有一個對從BO傳給他們的ISession的引用。他們負責自己的加載和保存:

public class EmployeeDTO... 

    // Data Properties to be persisted to the database 
    public virtual int Id { get; private set; } 
    public virtual string FirstName { get; set; } 
    public virtual string LastName { get; set; } 
    public virtual ISession Session { get; set; } 

    // Save logic 
    public virtual void Save() 
    { 
     var transaction = Session.BeginTransaction(); 
     Session.SaveOrUpdate(this); 
     transaction.Commit(); 
    } 

    // Load logic 
    public virtual void Load(int id)... 

首先: 這是採取正確的處理方法 - 應DTO必須保存和加載自己的能力嗎?

其次: 無論在哪裏保存/加載代碼就在於,你應該使用相同的Isession的壽命或對象,或者他們應該有一個裁判的ISessionFactory並打開一個新的會話,每次數據庫交互是必須的?

// Open a new session every time I interact with the repository 
    var session = FluentSupport.SessionFactory.OpenSession(); 
    var transaction = Session.BeginTransaction(); 
    Session.SaveOrUpdate(this); 
    transaction.Commit(); 
    session.Close(); 
    // Close the session when I'm done 

當然總是有選項3,以上都不是:)

+0

當一個對象知道如何保存自己被稱爲DAO,這與DTO – 2011-01-01 16:53:43

回答

10

一般來說,DTO的不包含的行爲(如保存,載入),不包含他們得到怎樣堅持知識(的Isession )。這聽起來像你真正創建的是一個數據層。理想情況下,您的業務層不應該瞭解ISession。也就是說,您可以根據自己的需要簡化所需的所有層,但如果您的ORM在所有層中流血,則可能稍後難以更改爲不同的ORM。

對於ISession生存期管理,您必須決定是否要使用UnitOfWork模式,它基本上說每個用戶請求都獲得一個新的ISession。 ISession的生命週期還有其他的選擇,你真的不受限於這方面。通常,圍繞Web應用程序與Windows應用程序或任何其他應用程序類型的最佳做法可能存在差異,但是您並未指定您正在編寫的內容。

+0

無關,該架構必須同時支持web(Silverlight)和Windows(WPF) – Steve 2009-10-07 09:09:51

+0

我已經澄清了這個問題以解決這個問題。 .. – Steve 2009-10-07 09:11:51

2

ISession打開/關閉非常便宜。將其保持打開時間過長的問題是連接池無法重新使用連接,直到超時或不連接爲止。這可能是多用戶應用程序中的問題。

在你的場景中,我可能會採用面向服務的方法來存儲檢索數據。這意味着DTO只能在服務邊界內部使用。如果你需要複製看起來相同的物體,我建議你看看爲此特定目的而創建的AutoMapper。如果你有一個只有Windows的或只有Web的項目,那麼這不是問題。這是當你混合。您無法在Windows應用程序中以與Web應用程序相同的方式處理會話。

9

保持您的加載/保存代碼與DTO分開。 DTO對象只是底層數據的視圖

在進行查詢時,通過使用轉換返回DTO。像這樣:

resultSet = session.CreateCriteria(typeof(MyDataObject)) 
    .Add(query criteria, etc.) 
    .SetResultTransformer(Transformers.AliasToBean<MyDTOObject>()) 
    .List<IMyDTOObject>()
+0

我可以在Add方法中使用哪種標準(將域屬性鏈接到DTO屬性)? – 2014-03-08 05:43:28

+0

@SilvioDelgado:對不起,我3年沒有和NHibernate合作過,所以我不知道。 – 2014-03-08 20:47:58

+0

沒問題。不管怎樣,謝謝你。 :) – 2014-03-09 23:58:26

3

DTO的意思是「數據傳輸對象」。也就是說,用於在系統中傳遞值或值集合的啞對象。他們不應該爲自己堅持自己負責,甚至不應該將1-1映射到域圖層中的域對象。