2012-05-26 91 views
0

在我的應用程序中,我一直在使用將其ID存儲爲字符串的數據庫。 DB還爲每個文檔/行存儲另一個屬性(Etag)。正因爲如此,我有我的域實體從這個基類派生:更改持久層時更改域實體

public class EntityBase : NotifyPropertyChangedBase 
{ 
    public string Id { get; set; } 
    public Guid ETag { get; set; } 
} 

現在我加入另一個數據層到我的申請,我不想刪除舊的。能夠基於運行時間決定切換並使用特定數據層將是很好的。問題是我想將Id作爲int存儲在新的數據庫中。在新的數據庫中,ETag是一個不必要的概念。

我很擔心如何管理這種變化。如果我將EntityBase.Id更改爲int,那麼舊數據層將不會編譯。如果使用舊的數據層,我想使用某個EntityBase,如果我使用的是新的數據層,則使用不同的EntityBase。這只是一個想法。也許有更好的方法?有關我如何完成這項工作的任何建議?

順便說一句,我認爲持久層問題不應該在域層對象(如Id是一個字符串或int)的方式工作。但是,太遲了,這就是我發現自己的情況。我希望有人對如何着手有一些很好的建議。

我在想添加ID2與EntityBase:

public class EntityBase : NotifyPropertyChangedBase 
{ 
    public string Id { get; set; } 
    public int Id2 { get; set; } // New property for new DB only 
    public Guid ETag { get; set; } 
} 

然後,在我的新DAL映射,我會在表格中的ID列映射到Id2的,而不是編號。但這不起作用,因爲我的業務邏輯僅引用Id。還在想......我可能會被卡住......

作爲一種破解,我可以讓EntityBase保持其原有形式。然後,在新的DAL中,當我執行ORM時,我可以將表的ID轉換爲字符串。

回答

0

我建議再添加一層。 例如,創建一個新的階級是這樣的:

public abstract class CommonEntityBase<T> : NotifyPropertyChangedBase{ 
    public T Id {get;set;} 
} 

,然後從這個類派生你的舊EntityBase:

public class EntityBase : CommonEntityBase<string>{ 

    //this property is present only in this old implementation 
    public Guid ETag { get; set; } 
} 

所以,現在,你可以創建一個新層,使用基類爲該還有:

public class FancyEntityBase : CommonEntityBase<int>{ 
    //No ETag concept here - ad new properties, methods, etc. 
} 

然而,有一個問題,如果你真的需要改變你的主鍵是整數。 這可能會導致使用ORM時的性能問題。

+0

通過這種方法,我認爲我仍然有一個問題。我的域實體從哪些方面獲得?有了這個解決方案,我不需要根據哪個持久層被使用來改變基類嗎?例如,當使用一個DAL時,Foo將從EntityBase派生,而當使用另一個DAL時,Foo將從FancyEntityBase派生。這會在編譯時改變層次結構。沒有? –

+0

我不認爲從DAL實體派生域實體是一個好主意 - 您將它們緊密耦合在一起,這就是爲什麼現在有這個問題(這是OCP違規)。如果你有一個「去耦合」代碼,你可以使用依賴注入方法與DI容器結合,並根據運行時決策在你的組合根處注入不同的對象圖(這可能是你的情況的一個版本號 - isn是嗎?)。不幸的是,我沒有看到一個簡單的方法來解決它。該領域應該首先與數據庫關注分離。 – Mikhail

+0

我認爲你是對的;一旦我最初決定讓任何來自數據層的東西蔓延到領域模型中,那就是真正的問題。要解決這個問題,我需要消除這個障礙。謝謝。 –