我需要为应用程序实现一个后台层。它将必须通过 EF4 实现数据访问,并通过 WCF 服务将数据访问公开为 CRUD。使用 WCF 数据服务不是一种选择,因为要求是公开 TCP 服务端点。
我在 Vs 2010 中看到 EF 附带了三个用于 EF 的代码生成器模板:
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; }
EntityObject
生成器自跟踪实体生成器,生成从
ObjectContext
和实体派生的上下文作为实现IObjectWithChangeTracker
和INotifyPropertyChanged,
的 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
的简单增强,实现了 ClearItems
和 InsertItem,
如下
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 以及实现此最佳实践的一些指南征求意见。
谢谢
最佳答案
- 这可能是您提到的那些方法中最好的方法,但需要付出最大的努力。首先,您必须通过 WCF 使实体可序列化 = 您必须修改生成器以使用
DataContract(IsReference = true)
和DataMember
属性,否则您将获得序列化对象图时出现循环引用异常(实体及其关系,其中主体和从属都具有彼此的导航属性)。使用对象图后,您还必须进行自己的更改跟踪或数据合并,因为 you will not know about changes made on client .如果您不打算传输对象图,而只是传输单个对象或相同对象的列表,那么您应该可以使用这种方法。 EntityObject
特定于 Entity Framework,将其暴露给客户不是一个好主意。默认情况下,它可由 WCF 序列化,但它也会传输 EF 特定信息,如EntityKey
。服务点应该是隐藏其内部实现,暴露基于EntityObject
的实体违反了该规则。它也没有解决更改跟踪问题。- STE 专为 scenario where you want to know about changes in object graphs 而设计为客户制作,但它们不是 Elixir 。服务和客户端应该只共享描述交换消息的契约。 STE 违反此规则,因为它们包含逻辑并且客户必须知道并使用此逻辑。 STE 基于在服务和所有客户端之间共享实体程序集 = clients must be .NET application或者必须在非 .NET 平台上重新实现相同的逻辑。他们也总是传输整个对象图——如果你在图中加载 100 个实体,将它们发送回客户端,客户端将更改图中的单个实体,它默认将所有 100 个实体发送回服务。
- POCO 生成器与第一种方法大体相同。它只是使用 ObjectContext API 而不是 DbContext API。修复方法是特定于服务的,客户不会知道它们。
最后一种方法是使用自定义非实体类(DTO = 数据传输对象)并在您的服务中隐藏 DTO 和实体之间的转换。这将允许您创建更复杂和更合适的对象集,但它也会使您的应用程序更加复杂并增加开发复杂性。在实现您自己的更改跟踪的情况下,这也是一个选项。
关于wcf - WCF 的 CRUD DAL Entity Framework 的推荐结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7703067/