我正在尝试确定如何最好地构建.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密封?)
由于
答案 0 :(得分:3)
您可以尝试以下方法来改进:
我个人更喜欢比管理器模型更丰富的模型,因为正如你所说,你最终会得到一堆静态方法,你不可避免地会在其他静态方法中将它们链接在一起。我觉得这个太乱了,更重要的是,在任何给定的时间点都难以理解并保证对象的一致性。
如果将逻辑封装在类本身中,则可以更加确定对象的状态,而不管外部调用者的性质如何。
顺便提一个好问题。
答案 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对象上拥有“虚拟”属性,并让管理器将其转换回其组件。