.NET实体框架项目布局(架构)

时间:2009-02-14 12:56:15

标签: c# asp.net entity-framework architecture web-architecture

我正在尝试确定如何最好地构建.NET实体框架项目以实现一个很好的分层方法。到目前为止,我已经在基于浏览的游戏中尝试过,玩家拥有并操作行星。这是我如何得到它:

网站

这包含所有前端。

C#Project - MLS.Game.Data

这包含带有我所有数据映射的EDMX文件。这里别无其他。

C#Project - MLS.Game.Business

这包含我称之为'Managers'的各种类,例如PlanetManager.cs。行星管理器有各种用于与行星交互的静态方法,例如 getPlanet(int planetID),它将从MLS.Game.Data返回生成的代码对象。

从网站上我会做这样的事情:

var planet = PlanetManager.getPlanet(1);

它从MLS.Game.Data(从EDMX生成)返回 Planet 对象。它有效,但它在某种程度上困扰我,因为这意味着我的前端必须引用MLS.Game.Data。我一直认为GUI应该只需要引用Business项目。

此外,我发现我的经理课程往往变得非常沉重。我最终会得到几十种静态方法。

所以...我的问题是 - 其他人如何布置他们的ASP EF项目?

修改

经过一些更多,还有其他项目让我烦恼。例如,假设我有我的Planet对象,它再次从向导生成代码。如果时间到来我的星球需要有一个专门的属性,比如说“人口”,这是基于Planet对象的其他属性的某种计算。我是否想要创建一个继承自Planet的新类,然后返回它? (嗯,我想知道这些课程是否被EF密封?)

由于

7 个答案:

答案 0 :(得分:3)

您可以尝试以下方法来改进:

  • 使用EF在您的数据层中获取DTO,然后使用这些DTO在您的业务层中填充更丰富的业务对象。您的UI只需要引用业务层。
  • 创建富业务对象后,您可以开始内部化管理器类中的某些逻辑,从而有效地清理业务层。

我个人更喜欢比管理器模型更丰富的模型,因为正如你所说,你最终会得到一堆静态方法,你不可避免地会在其他静态方法中将它们链接在一起。我觉得这个太乱了,更重要的是,在任何给定的时间点都难以理解并保证对象的一致性。

如果将逻辑封装在类本身中,则可以更加确定对象的状态,而不管外部调用者的性质如何。

顺便提一个好问题。

答案 1 :(得分:2)

恕我直言,你目前的布局很好。在您调用它时,您的UI引用“数据”层是完全正常的。我想也许你的担忧可能是由于术语引起的。您所描述的“数据”通常被称为“业务对象”(BOL)层。然后,通用布局将具有业务逻辑层(BLL),即您的“管理器”层和数据访问层(DAL)。在您的场景中,LINQ to Entites(假设您将使用它)是您的DAL。那么正常的参考模式将是: -

UI引用BLL和BOL。 BLL重新支持BOL和DAL(LINQ to Entites)。

请查看this series of articles了解更多详情。

答案 2 :(得分:2)

至于你的第二个问题(编辑之后)如果你需要或想要为EF对象添加功能,你可以使用部分类。右键单击EDMX文件并选择查看代码。

或者如果这还不够,你可以抛弃设计师并编写自己的EF启用类。

这里有两个选项的(简短的)讨论 - http://msdn.microsoft.com/en-us/library/bb738612.aspx

答案 3 :(得分:1)

关于你在“编辑”部分的第二个问题:

如果我没弄错的话,EF生成的类没有密封,它们是 PARTIAL 类,所以你可以轻松地扩展它们而不用触及生成的文件本身。

生成的类将是:

public partial class Planet : global::System.Data.Objects.DataClasses.EntityObject
{
 ...
}

因此您可以轻松创建自己的“PlanetAddons.cs”(或任何您想要的名称)来扩展此类:

public partial class Planet 
{
 property int Population {get; set;} 
 ...
}

非常整洁,是吗?无需派生和创建人工对象层次结构....

马克

答案 4 :(得分:0)

我不是专家,但这对我来说听起来不错。这与我的解决方案类似,只是我将EF项目与业务项目合并。我的解决方案并不是那么大,而且我的对象不需要很多智能,所以它对我来说很好。我的每个静态辅助类都有很多不同的方法。

如果您不希望表示层知道数据访问层,那么您必须创建一些中间类,这可能需要很多工作。那你当前的设置有什么问题吗?

答案 5 :(得分:0)

您的布局看起来不错。 我会添加一个Utility / Common图层

Web UI
业务层
数据对象
实用工具层

答案 6 :(得分:0)

我会将DTO添加到您的业务层,这是您数据层中实体的“哑对象”表示(即仅属性)。然后您的“经理”类可以返回它们,例如:

class PlanetManager
{
    public static PlanetDTO GetPlanet(int id) { // ... }
}

并且您的UI只能通过POCO处理BLL层;管理器(我称之为“Mapper”类)处理对象和数据层之间的所有转换。此外,如果您需要扩展该类,您可以在DTO对象上拥有“虚拟”属性,并让管理器将其转换回其组件。