2012-01-24 104 views
0

延遲加載我單獨我的域邏輯從我的web服務邏輯與NHibernate流利,Web服務和automapper

這是我的域名,實際上從NHibernate的

public static IList<Location> LoadReturnLocationsFromDatabase(DateTime lastUpdateTime) 
{ 
    using (var session = NHibernateHelper.OpenSession()) 
    { 
     // retreive all stores and display them 
     using (session.BeginTransaction()) 
     { 
      var locations = session.CreateCriteria(typeof(Location)).Add(Expression.Gt("LastUpdatedTime", lastUpdateTime)).SetMaxResults(10).List<Location>(); 
      return locations; 
     } 
    } 
} 

此數據獲取數據然後返回到Web服務我用Automapper複製它,以不公開的數據庫訪問對象的網絡服務,並保持所有的東西獨立。

public IList<GetLocationDetailsResponse> GetLocationUpdate(DateTime lastUpdateTimeDT) 
{ 

    Mapper.CreateMap<Location, GetLocationDetailsResponse>(); 

    IList<Location> locations = WhygoDomain.GetLocations.LoadReturnLocationsFromDatabase(lastUpdateTimeDT); 

    IList<GetLocationDetailsResponse> getLocationDetails = Mapper.Map<IList<Location>, IList<GetLocationDetailsResponse>>(locations); 
    return getLocationDetails; 
} 

我的問題是我不能做的映射,除非我指定的位置和狀態之間的關係是不懶加載,因爲Web服務是外:在數據

using (var session = NHibernateHelper.OpenSession()) 

域。

延遲加載似乎是做這樣的事情的首選方法,所以我想知道如果這種方法好不好?這是一個數據導出服務,將導出內存使用情況等最終可能會有問題。

如果我需要改變這一點,是這個問題的原因我的代碼結構?如果是這樣,我怎麼能保持我的域邏輯獨立,並解決這個問題?

+0

您是否有AOP框架? –

回答

2

預先抓取

您可以避免這個問題通過與地方一起熱切取狀態達到更好的性能 - 否則,你有什麼叫做「選擇N + 1」的問題。見Ayende的博客,就是一個很好的解釋: http://ayende.com/blog/1328/combating-the-select-n-1-problem-in-nhibernate

實質上,每次訪問不同的location.State時都會執行一個單獨的SQL查詢,這可能意味着您的案例中多達11次往返數據庫。如果位置查詢包含在LEFT OUTER JOIN的狀態,那麼所有需要的數據可以在一個單一的往返到數據庫中讀取。

在你的情況,下面的查詢可能會更好地工作:

var locations = session.CreateCriteria(typeof(Location)) 
    .Add(Expression.Gt("LastUpdatedTime", lastUpdateTime)) 
    .SetMaxResults(10) 
    .SetFetchMode("State", FetchMode.Eager) 
    .List<Location>(); 

依賴倒置

您遇到的問題闡明一個事實,即GetLocations不足夠了解的情況來定負責創建和銷燬NHibernate會話。 NHibernate會話的創建至少需要向上移動一層。當然,還有在做這一切,就像使用IoC容器的更優雅的方式,但這裏的一些快速和骯髒的代碼來說明我的意思:

public IList<GetLocationDetailsResponse> GetLocationUpdate(DateTime lastUpdateTimeDT) 
{ 
    using (var session = NHibernateHelper.OpenSession()) 
    { 
     var locations = GetLocations.LoadReturnLocationsFromDatabase(session, lastUpdateTimeDT); 
     return Mapper.Map<IList<Location>, IList<GetLocationDetailsResponse>>(locations); 
    } 
} 

最後一點:AutoMapper的Mapper.CreateMap是靜態的設置代碼,只需要在應用程序啓動時執行一次。 Global.asax是該類型代碼的最佳位置。

2

,因爲你需要一個開放的會議,能夠從連接的域對象分離的自動映射對象映射,你必須確保會議是開放的,而你是自動映射。您可以考慮將您的使用聲明移至Web服務調用,而不是將其用於域方法中。

+0

我知道你在說什麼,但似乎擺脫了分離的Web服務和域的整個點...也許我已經分離它已經雖然... – iKode

+0

我不知道這是最好不是延遲加載數據 – iKode

+0

@iKode:如果在加載後直接訪問其所有屬性,那麼延遲加載數據沒有任何意義。 –