wcf - WCF 的 CRUD DAL Entity Framework 的推荐结构

标签 wcf entity-framework entity-framework-4 crud

我需要为应用程序实现一个后台层。它将必须通过 EF4 实现数据访问,并通过 WCF 服务将数据访问公开为 CRUD。使用 WCF 数据服务不是一种选择,因为要求是公开 TCP 服务端点。

我在 Vs 2010 中看到 EF 附带了三个用于 EF 的代码生成器模板:

  1. DbContext 生成器,生成从 DbContext 派生的上下文和实体类作为非常简单的 POCO,没有额外的代码;

    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 和实体派生的上下文作为实现 IObjectWithChangeTrackerINotifyPropertyChanged, 的 POCO 类和辅助类 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 以及实现此最佳实践的一些指南征求意见。

谢谢

最佳答案

  1. 这可能是您提到的那些方法中最好的方法,但需要付出最大的努力。首先,您必须通过 WCF 使实体可序列化 = 您必须修改生成器以使用 DataContract(IsReference = true)DataMember 属性,否则您将获得序列化对象图时出现循环引用异常(实体及其关系,其中主体和从属都具有彼此的导航属性)。使用对象图后,您还必须进行自己的更改跟踪或数据合并,因为 you will not know about changes made on client .如果您不打算传输对象图,而只是传输单个对象或相同对象的列表,那么您应该可以使用这种方法。
  2. EntityObject 特定于 Entity Framework,将其暴露给客户不是一个好主意。默认情况下,它可由 WCF 序列化,但它也会传输 EF 特定信息,如 EntityKey。服务点应该是隐藏其内部实现,暴露基于 EntityObject 的实体违反了该规则。它也没有解决更改跟踪问题。
  3. STE 专为 scenario where you want to know about changes in object graphs 而设计为客户制作,但它们不是 Elixir 。服务和客户端应该只共享描述交换消息的契约。 STE 违反此规则,因为它们包含逻辑并且客户必须知道并使用此逻辑。 STE 基于在服务和所有客户端之间共享实体程序集 = clients must be .NET application或者必须在非 .NET 平台上重新实现相同的逻辑。他们也总是传输整个对象图——如果你在图中加载 100 个实体,将它们发送回客户端,客户端将更改图中的单个实体,它默认将所有 100 个实体发送回服务。
  4. POCO 生成器与第一种方法大体相同。它只是使用 ObjectContext API 而不是 DbContext API。修复方法是特定于服务的,客户不会知道它们。

最后一种方法是使用自定义非实体类(DTO = 数据传输对象)并在您的服务中隐藏 DTO 和实体之间的转换。这将允许您创建更复杂和更合适的对象集,但它也会使您的应用程序更加复杂并增加开发复杂性。在实现您自己的更改跟踪的情况下,这也是一个选项。

关于wcf - WCF 的 CRUD DAL Entity Framework 的推荐结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7703067/

相关文章:

entity-framework - 如何在 EF4 中获取实体的第一个 EntityKey 名称

jquery - 将 jQuery 中的 WCF 作为 JSON 使用

.net - Entity Framework nvarchar外键区分大小写

wcf - 通过 ADFS 对 Web 服务的用户进行身份验证

asp.net - 如何在 Entity Framework 核心中调用标量函数

entity-framework - ASP.Net 核心 : Cannot open localdb requested by the login

c# - 检索 Entity Framework 中的存储过程输出参数始终为空

wcf - Silverlight:企业级推送通知

.net - 在 PHP 中连接到具有 NetTCP 绑定(bind)和 BasicHttpBinding 的 WCF 服务