2011-07-21 53 views
1

使用一个简单的例子:实体框架在N层

  • 表示层:ASPX和代码的后面。
  • 业务层:WCF与 相关的逻辑
  • 数据访问层:WCF与实体框架

当我想填充网格视图,将有需要调用一个方法形成的商业逻辑,后者依次调用数据访问层的方法。

方法和相关逻辑如下。

数据访问层:

public SampleEntity[] LoadSampleEntity() 
{ 
    //retrieve SampleEntity from database. 
} 

业务逻辑层:

public SampleEntity[] GetSampleEntity() 
{ 
    //call the proxy to access Data Access Tier 
    //Call LoadSampleEntity() 
} 

表示层:

protected void btn_OnClick() 
{ 
    //call the proxy to access Business Logic Tier 
    //Call GetSampleEntity() 
    //SampleEntity[] sampleEntity=BusinessLogic.GetSampleEntity(); 
    //gridview.datasouce = sampleEntity 
    //gridview.databind(); 
} 

鉴于这种结构,如果SampleEntity被修改,所有的3层会需要重新编译。
当新的属性/列添加到SampleEntity时,有什么办法可以减少重新编译的需要吗?我曾经参与

的一种方式将是SampleEntity []转换为数据表型在业务逻辑层,并通过数据表到表示层。但是,这样做会删除Presentation Tier中的EntityFramework的智能感知功能。

回答

1

您可以尝试存储库模式。您首先会有一个与您的实体对象类似的对象的域图层,该域图层将位于它自己的项目/ dll中。您可以使用类似AutoMapper的东西,通过业务层将Entity对象的值映射到Domain对象。然后,表示层会/可以共享域对象层,这样你抽象的每个表的

IRepository<T> 
{ 
    IEnumerable<T> GetAll(); 
    T GetById(int id); 
    void Save(T saveThis); 
    void Delete(T deleteThis); 
} 

你的T型背后的实体数据层将域类型和这些方法里面你会映射实体类型为您的域类型。此IRepository可以是您在数据层访问上的服务合同。

至于你的其他问题,您对实体对象的任何改变都需要反映在域对象不过这可以通过类似AutoMapper来完成。我认为在大多数情况下,您不希望将EF或LinqToSql数据类型共享到视图或用户界面。

既然是WCF,你可以让域层为你的序列化类型。

+0

这对我很有用。我其实不想公开这个实体,而是做一些像你一样的事情。但我不确定是否有办法做到这一点,而不会影响我的开发时间。现在你来谈谈automapper。automapper是否像object.getType()?如果你不介意,你可以根据各种层次向我展示伪或代码吗?使用你的方法,我可以看到iRepository在业务层面上提供的帮助,但是就表现层而言,我应该如何访问T? –

+0

Automapper只是一种将状态从一个对象转移到另一个对象的方式,就像这样。你可以在codeplex上查看它,我使用自己的自制反射映射方案,但Automapper会做得更好。基本上你可以用上面显示的合同将每个表格表示为它自己的wcf存储库服务(尽管你真的不能在WCF中使用通用接口)。 –

+0

然而,您可能会或可能会将在合同/存储库中由T表示的您的域对象共享到表示层,就像您上面使用SampleEntity共享它一直到表示层一样。您的表示层只会了解从IRepository服务返回给您的域对象。它将无法知道实现此合约的服务内部(数据环境和转换到域对象的所有细节)。 –

0

您可能有兴趣使用在服务器端使用实体框架的开源N-Tier Entity Framework,并生成用于构建基于WCF的n层体系结构的整个基础架构,其中包括客户端上类似EF的API。看看框架的可供下载在CodePlex用户指南,它包含架构考虑的一整节。