12

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

网站

这包含所有的前端。

C# 项目 - MLS.Game.Data

这包含带有我所有数据映射的 EDMX 文件。这里不多。

C# 项目 - MLS.Game.Business

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

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

var planet = PlanetManager.getPlanet(1);

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

此外,我发现我的 Manager 课程往往会变得非常繁重。我最终会得到几十个静态方法。

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

编辑

不过,再过一些之后,还有一些让我烦恼的东西。例如,假设我有我的 Planet 对象,它也是由向导生成的代码。如果有一天我的星球需要有一个专门的属性,比如说“人口”,它是基于星球对象的其他属性的某种计算。我想创建一个继承自 Planet 的新类然后返回它吗?(嗯,我想知道这些类是否被 EF 密封?)

谢谢

4

7 回答 7

3

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

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

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

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

顺便说一句,一个很好的问题。

于 2009-02-14T13:29:52.337 回答
2

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

UI 引用 BLL 和 BOL。BLL 引用 BOL 和 DAL (LINQ to Entites)。

请查看本系列文章以获取更多详细信息。

于 2009-02-14T13:33:36.900 回答
2

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

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

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

于 2009-02-14T16:17:06.587 回答
1

至于“编辑”部分中的第二个问题:

如果我没记错的话,EF 生成的类不是密封的,它们是PARTIAL类,因此您可以轻松扩展这些类,而无需接触生成的文件本身。

生成的类将是:

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

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

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

很整洁,嗯?无需派生和创建人工对象层次结构......

马克

于 2009-02-26T17:18:15.503 回答
0

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

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

于 2009-02-14T13:10:28.203 回答
0

你的布局看起来不错。我会添加一个实用程序/公共层

Web UI
业务层
数据对象
实用程序层

于 2009-02-14T14:16:18.933 回答
0

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

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

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

于 2009-02-16T16:01:54.270 回答