开发者

Recommended structure for entity framework for a CRUD DAL for WCF

I need to implement a back-office layer for an application. It will have to implement the data access through EF4, and expose the data access as CRUD through WCF services. The using of WCF Data Service is not an option, because the requirements are to expose a TCP service endpoint.

I see EF in Vs 2010 comes with three code-generator templates for EF:

  1. DbContext generator, generates the context derived from DbContext and the entity classes as very simple POCO's with no extra code;

    public partial class MyEntities : DbContext
    {...}
    

    And entity classes

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

  3. Self-tracking entity generator, that generates the context derived from ObjectContext and entities as POCO classes implementing IObjectWithChangeTracker and INotifyPropertyChanged, and helper class ObjectChangeTracker

And I found another one on the internet, POCO entity generator, which generates the context based on ObjectGenerator and the entity classes开发者_Go百科 as POCO with extra code for tracking navigation properties, as below:

    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; 

where FixupCollection is a simple enhancement of ObservableCollection, implementing ClearItems and InsertItem, as below

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);
        }
    }
} 

I would like to ask for advise on which of them would be more appropriate for using to implement the CRUD over a WCF service, and some guidelines on best practices implementing this.

Thanks


  1. This is probably the best approach from those you mentioned but it will require the biggest effort. First of all you will have to make your entities serializable by WCF = you will have to modify generator to use DataContract(IsReference = true) and DataMember attributes because otherwise you will get cyclic reference exception when serializing object graph (entity with its relations where both principal and dependent have navigation property to each other). Once using object graphs you will also have to make your own change tracking or data merging because you will not know about changes made on client. If you don't plan to transfer object graphs but only single objects or list of the same objects you should be OK with this approach.
  2. EntityObject is specific to Entity Framework and exposing it to clients is a bad idea. It is by default serializable by WCF but it also transfers EF specific information like EntityKey. The point of service should be to hide its internal implementation and exposing EntityObject based entities is violation of that rule. It also doesn't solve change tracking problem.
  3. STEs are designed for the scenario where you want to know about changes in object graphs made on clients but they are not a silver bullet. Services and clients should share only contract describing exchanged messages. STEs violate this rule because they contain logic and client must know and use this logic. STEs are based on sharing entity assembly between service and all clients = clients must be .NET application or the same logic must be reimplemented on non-.NET platform. They also always transfer whole object graph - if you load 100 entities in graph send them back to client and client will make change to single entity in graph it will by default send all 100 entities back to the service.
  4. POCO generator is generally the same as the first approach. It just uses ObjectContext API instead of DbContext API. Fixup methods are service specific and client will not know about them.

The last approach is using custom non entity classes (DTOs = Data transfer objects) and hide conversion between DTOs and entities in your service. That will allow you to create more complex and suitable set of objects but it will also make your application more complex and increase development complexity. This will be also option in case of implementing your own change tracking.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜