WCF CRUD DAL 实体框架的推荐结构
我需要为应用程序实现后台层。它必须通过 EF4 实现数据访问,并通过 WCF 服务将数据访问公开为 CRUD。使用 WCF 数据服务不是一种选择,因为要求是公开 TCP 服务端点。
我看到 Vs 2010 中的 EF 附带了 EF 的三个代码生成器模板:
DbContext
生成器,生成从DbContext
派生的上下文和非常简单的 POCO 实体类没有额外的代码;公共分部类 MyEntities : DbContext {...}
和实体类
<前><代码>.... 公共 int EmailAddressLocatorID { 获取;放; } .... 公共虚拟地址Address { get;放; } .... 公共虚拟 ICollectionHouseholdGuests { 得到;放; } EntityObject
生成器自跟踪实体生成器,生成从
ObjectContext
和实体作为 POCO 类实现IObjectWithChangeTracker
和INotifyPropertyChanged,
和辅助类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,以及实现此功能的最佳实践的一些指南。
谢谢
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:
DbContext
generator, generates the context derived fromDbContext
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; }
EntityObject
generatorSelf-tracking entity generator, that generates the context derived from
ObjectContext
and entities as POCO classes implementingIObjectWithChangeTracker
andINotifyPropertyChanged,
and helper classObjectChangeTracker
And I found another one on the internet, POCO entity generator, which generates the context based on ObjectGenerator
and the entity classes 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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
EntityObject
是特定于实体框架的,将其暴露给客户端是一个坏主意。默认情况下,它可由 WCF 序列化,但它也传输 EF 特定信息,例如EntityKey
。服务的重点应该是隐藏其内部实现,而暴露基于 EntityObject 的实体则违反了该规则。它也没有解决变更跟踪问题。最后一种方法是使用自定义非实体类(DTO = 数据传输对象)并隐藏服务中 DTO 和实体之间的转换。这将允许您创建更复杂和合适的对象集,但它也会使您的应用程序更加复杂并增加开发复杂性。如果您要实现自己的更改跟踪,这也是一个选项。
DataContract(IsReference = true)
andDataMember
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.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 likeEntityKey
. The point of service should be to hide its internal implementation and exposingEntityObject
based entities is violation of that rule. It also doesn't solve change tracking problem.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.