对于 3 层 WPF 应用程序的体系结构有不同的解决方案,但这里有一种可能性:
1+2) 一种解决方案是创建代表客户端应用程序实际需要的“中间”对象。例如,如果您的应用程序需要显示有关产品的信息以及相关的客户名称,您可以构建以下对象:
public MyProduct
{
// Properties of the product itself
public int ProductID { get; set; }
public string ProductName { get; set; }
...
// Properties that come from the Customer entity
public string CustomerName { get; set; }
}
然后,您可以公开一个无状态的 WCF 服务,该服务从一个 ID 返回您的产品:
[ServiceContract]
MyProduct GetProductByID(int productID);
在应用程序的服务器端(即服务的实现),您可以MyProduct
通过 EF 查询数据库返回一个实例构建(每次调用一个上下文):
public MyProduct GetProductByID(int productID)
{
using (DBContext ctx = new ....)
{
return from p in ctx.Products
where p.ID == productID
select new MyProduct
{
ProductID = p.ID,
ProductName = p.Name,
CustomerName = p.Customer.Name // Inner join here
};
}
}
3) 在 WCF 服务和 ViewModel 之间添加额外的层可能被认为是过度工程。恕我直言,可以直接从 ViewModel 调用 WCF 服务。WCF 生成的客户端代理代码具有模型的实际作用(至少是模型的一部分)。
编辑:
为什么 MyProduct 应该引用 CustomerName 而不是 Customer。在我的例子中,Customer 会有很多我可以使用的属性。这个“映射”不会太贵吗?
您可以使用实际的实体。但在客户端,由于它是 3 层架构,您无法通过导航属性访问数据库。如果存在嵌套Customer
属性(类型为Customer
),则客户端将有权访问theProduct.Customer.Products
,如果您不能以这种方式延迟加载实体(客户端没有数据库上下文),这毫无意义。
扁平的“中间”POCO 更简单 IMO。没有性能问题,映射很简单,与 DB 请求时间相比,此特定操作的 CPU 使用率是无限小的。