2010-10-08 45 views
1

我正在網站上工作,解決方案中有兩個項目是業務邏輯項目和網站項目。我知道我想將實體上下文保留在Web項目之外,只使用框架創建的業務對象,但我無法弄清楚如何以這種方式保存修改後的對象。ASP.NET EntityFramework 4數據上下文問題

比方說,我的實體模型創建這個類:

public class Person //Person entity 
{ 
    Int32 Id {get;set;} 
    String Name {get;set;} 
    Address Address {get;set;} //Address entity 
} 

,我創建了這個類來獲得一個特定的人:

public static class PersonController 
{ 
    public static Person GetById(int id) 
    { 
     using (Entities context = new Entities()) 
     { 
      return context.Persons.FirstOrDefault(x => x.Id == id); 
     } 
    } 
} 

這讓我通過打電話來想一個人沒有上下文PersonController.GetById(1);我可以在獲取它們後更改人員屬性,但我無法弄清楚如何將修改後的信息保存回數據庫。理想情況下,我想部分類Person,並添加一個.Save()方法,該方法將處理創建一個上下文並將其添加到其中並保存更改。但是當我前一陣子嘗試時,它仍然存在各種各樣的問題,它仍舊附加到舊的上下文中,即使我將它解鎖並將它附加到一個新的上下文,它將作爲EntityState.Unchanged被附加,如果我沒有記錯,那麼當我在附加它後調用context.SaveChages()時,實際上沒有任何更新。

我想我有兩個問題:

1)我要對這個的一個好辦法/有沒有更好的辦法?如果我以一種非常可怕的方式來做這件事,我會很感激一些psudo-code讓我指出正確的方向;一個解釋如何去做這種事情的帖子的鏈接也會起作用。

2)有人可以提供一些保存方法的psudo代碼?如果地址被附加或刪除,save方法也需要處理。

回答

1

有許多方法可以將實體框架作爲持久層處理。

首先,它看起來像你不使用純POCO的。也就是說,您讓EF爲您生成類(在EDMX.designer.cs文件中)。

這沒有錯,但它確實抑制了一個清晰的關注點(特別是在單元測試時)。

您是否考慮實施Repository模式來封裝您的EF邏輯?這將是從您的用戶界面中分離邏輯的好方法。

在保存方面 - 這是困難的地方。你是對的,大多數人使用部分班。通常,您將擁有一個基類,它公開了一個虛擬的「保存」方法,然後這些分類可以覆蓋。

我個人不喜歡這種模式 - 我相信POCO不應該關心持久性或底層基礎設施。因此,我喜歡使用純粹的POCO(無代碼代碼),存儲庫模式和工作單元。

工作單元處理您打開/保存/關閉的上下文。

這就是(我的)工作單元如何做到這一點。考慮此部分代碼在您的「網絡」項目:

var uOw = new UnitOfWork(); // this is class i created, implementing the UOW pattern 
var person = repository.Find(10); // find's a "Person" entity (pure POCO), with id 10. 
person.Name = "Scott"; 
uOw.Commit(); 

或添加新聯繫人:

var uOw = new UnitOfWork(); 
var newPerson = new Person { Name = "Bob" }; 
repository.Add(newPerson); 
uOw.Commit(); 

真好是什麼? :)

第1行爲您創建一個新的sql上下文。 第2行使用相同的上下文來檢索單個「Person」對象,該對象是手動編碼的POCO(不是由EF生成的)。 第3行更改Person(純POCO setter)的名稱。 第4行保存對數據上下文的更改,並關閉上下文。

現在,這些模式比這個更多,所以我建議你閱讀這些模式,看看它是否適合你。

我的存儲庫也使用泛型實現,所以我可以重新使用此接口來實現所有業務實體持久性。

另請參閱我在StackOverflow上詢問的其他一些問題 - 您可以看到我是如何實現這些模式的。

不知道這是您尋找的「答案」,但我想我會給你一些替代選擇。

希望這會有所幫助。

+0

我是一個漂亮的新開發者,所以我沒有很多設計模式的經驗。因此我不知道如何使用存儲庫模式,但我可以查看。爲什麼你不想使用EF生成的對象呢?我認爲EF的重點在於它能夠自動生成對象,並且可以爲您節省時間編碼;這兩方面你都不需要編寫代碼,而且你沒有測試你不寫的代碼。 – William 2010-10-09 19:04:24

+0

那麼有太多的原因,太多不能進入這裏。主要的是可擴展性。如果你讓EF生成你的類,這些類與EF綁定,並且是數據庫感知的。他們需要知道他們如何被使用(映射)。有了POCO,他們不知道。因此,您可以將EF轉換爲nHibernate(例如),而無需額外更改代碼。此外,您的課程現在純粹代表您的領域模型 - 它們不會與導航屬性和事件代表混雜在一起。對於簡單的應用程序(不會長期存在的),EF gen很好。 – RPM1984 2010-10-09 22:30:57

+0

RE測試 - 您不直接測試類,但例如如果您有服務層(大多數應用程序都是這樣),則需要確保您可以創建/檢索/刪除實體。通過使用code-gen,測試服務層時需要參考實體框架。這不應該被要求。你最終得到的是所有項目引用實體框架 - 因此你放棄了「鬆耦合」。 – RPM1984 2010-10-09 22:32:49