2011-10-09 75 views
3

我需要爲應用程序實現後臺層。它必須通過EF4實現數據訪問,並通過WCF服務將數據訪問公開爲CRUD。 WCF數據服務的使用不是一個選項,因爲要求是公開一個TCP服務端點。用於WCF的實體框架的推薦結構WCF

我看到EF在VS 2010中附帶了EF三種代碼生成模板:

  1. DbContext發生器,產生非常簡單的POCO的,沒有額外的代碼實體類從DbContext衍生的背景和;

    public partial class MyEntities : DbContext 
    {...} 
    

    類和實體類

    .... 
    public int EmailAddressLocatorID { get; set; } 
    .... 
    public virtual Address Address { get; set; } 
    .... 
    public virtual ICollection<HouseholdGuest> HouseholdGuests { get; set; } 
    
  2. EntityObject發電機

  3. 自我跟蹤實體發生器,產生從ObjectContext和實體獲得的上下文POCO類實現IObjectWithChangeTrackerINotifyPropertyChanged,和輔助類ObjectChangeTracker

而且我發現另一個在互聯網上,POCO實體發生器,其基於ObjectGenerator上下文和實體類如POCO與額外的代碼用於跟蹤導航屬性,如下:

public virtual ICollection<Guest> GuestsAddress 
    { 
     get 
     { 
      if (_guestsAddress == null) 
      { 
       var newCollection = new FixupCollection<Guest>(); 
       newCollection.CollectionChanged += FixupGuestsAddress; 
       _guestsAddress = newCollection; 
      } 
      return _guestsAddress; 
     } 
     set 
     { 
      if (!ReferenceEquals(_guestsAddress, value)) 
      { 
       var previousValue = _guestsAddress as FixupCollection<Guest>; 
       if (previousValue != null) 
       { 
        previousValue.CollectionChanged -= FixupGuestsAddress; 
       } 
       _guestsAddress = value; 
       var newValue = value as FixupCollection<Guest>; 
       if (newValue != null) 
       { 
        newValue.CollectionChanged += FixupGuestsAddress; 
       } 
      } 
     } 
    } 
    private ICollection<Guest> _guestsAddress; 

其中FixupCollection是的ObservableCollection一個簡單的增強,實現ClearItemsInsertItem,如下

public class FixupCollection<T> : ObservableCollection<T> 
{ 
    protected override void ClearItems() 
    { 
     new List<T>(this).ForEach(t => Remove(t)); 
    } 

    protected override void InsertItem(int index, T item) 
    { 
     if (!this.Contains(item)) 
     { 
      base.InsertItem(index, item); 
     } 
    } 
} 

我想問的提醒上他們會更適合ü通過WCF服務來實現CRUD,以及一些關於實現這一點的最佳實踐的指導方針。

感謝

回答

2
  1. 這可能是你所提到的那些最好的辦法,但它需要最大的努力。首先,你將不得不讓你的實體可以通過WCF序列化 - 你將不得不修改生成器來使用DataContract(IsReference = true)DataMember屬性,否則當序列化對象圖時(實體與其主體和從屬都有導航的實體財產對彼此)。一旦使用了對象圖,您還必須自己進行更改跟蹤或數據合併,因爲you will not know about changes made on client。如果您不打算傳輸對象圖,但只傳輸單個對象或相同對象的列表,則應使用此方法。
  2. EntityObject特定於實體框架並將其公開給客戶端是一個壞主意。默認情況下,它是由WCF序列化的,但它也傳輸EF特定信息,如EntityKey。服務點應該隱藏其內部實現,並暴露基於實體違反該規則。它也不解決變更跟蹤問題。
  3. STE是專門爲客戶製作的scenario where you want to know about changes in object graphs而設計的,但它們不是銀子彈。服務和客戶應共享描述交換消息的合同。STE違反了這條規則,因爲它們包含邏輯,客戶端必須知道並使用這個邏輯。 STE基於在服務和所有客戶端之間共享實體彙編= clients must be .NET application或相同的邏輯必須在非.NET平臺上重新實現。他們也總是傳輸整個對象圖 - 如果你在圖中加載100個實體,將它們發送回客戶端,客戶端將對圖中的單個實體進行更改,默認情況下會將全部100個實體發送回服務。
  4. POCO發生器與第一種方法大致相同。它只是使用ObjectContext API而不是DbContext API。 Fixup方法是服務特定的,客戶端不會知道它們。

最後一種方法是使用自定義非實體類(DTOs =數據傳輸對象)並隱藏服務中DTO和實體之間的轉換。這將允許您創建更復雜和適合的對象集合,但它也會使您的應用程序更復雜並增加開發複雜性。如果實施自己的更改跟蹤,這也是可選的。

+0

感謝您的建議。我開始使用DbContext方法 – bzamfir