2011-10-09 58 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