我们正在开发一个带有WPF客户端的3层应用程序,它通过WCF与BLL进行通信。我们使用EF访问我们的数据库。 我们一直在使用EF的默认EntityObject代码生成器,但是当通过网络发送这些对象时,以及在BLL中处理和重新附加它们时,会遇到很多问题和序列化问题。
我们即将切换到POCO模板,并重写数据访问和我们应用程序的通信部分(我们希望有一个更清晰的架构,而不是那种“魔术代码”。
我的问题是在客户端重用POCO类是否是个好主意?或者我们应该创建单独的DTO类?即使它们与POCO实体类相同?这两种方法的优缺点是什么?
答案 0 :(得分:3)
绝对使用DTOs + AutoMapper。否则,由于循环依赖性(尤其是导航属性存在问题),使用WCF时DataContractSerializer会遇到大量问题。即使您最初可能省略DTO,但由于上述问题,您将被迫在以后使用它们。所以我建议为每一层使用适当的DTO。
此外,您的特定于级别的模型将具有不同的属性。您可能还需要修改(即专门化)您在每个层中携带的数据。因此,如果您的项目足够大(或者有可能是这样),请使用具有适当命名的DTO并将它们放置在适当的位置(即不是所有位于同一组件中)。
答案 1 :(得分:2)
现在我处理类似的问题。我接下来做了:
SF.Contracts - 刚刚定义了ServiceCotnracts和DataContracts。很明显所有数据都可以像EF中的POCO类一样使用(但是我不使用t4或其他生成器 - 所有POCO类和DataContext都是手工编写的,因为我需要使用非常bad database)。 SF。
SF.DataAccessObjects - 在这个组件中我实现了我的edmx和DataContext。 SF.Services - WCF服务的实现。
因此,大量选择WCF方法具有下一个签名和实现:
public List<Vulner> VulnerSelect(int[] idList = null, string[] navigationPropertiesList = null)
{
var query = from vulner in _businessModel.DataModel.VulnerSet
select vulner;
if (navigationPropertiesList != null)
navigationPropertiesList.Select(p =>{query = ((ObjectQuery<Vulner>)query).Include(p);
return true; });
if (idList != null)
query = query.Where(p => idList.Contains(p.Id));
return query.ToList();
}
你可以像这样使用这个方法:
WCFproxy.VulnerSelect(new[]{1,2,3},new[]{"SecurityObjects", "SecurityObjrcts.Problem"});
这样,您就没有serrialization,导航属性等方面的问题,您可以清楚地指出必须加载哪些NavigationProperties。
p.s。:我的英语不好的sory:)
答案 2 :(得分:1)
我会说使用DTO。
循环依赖关系和大对象图可能是一个严重的问题,导致错误或过多的序列化流量。 ORM控制对象上的噪声太大,无法将其发送到线路上。
我使用服务层来访问我的域对象并广泛使用LINQ,但我总是将DTO对象返回给客户端。