这是一个特定的问题,但我无法弄清楚如何让所有部分正确地结合在一起。我正在尝试使用实体框架使用SQL Server数据库启动项目,以使用AngularJS前端为BreezeJS提取数据。我的问题主要集中在N-Tier和BreezeJS关系以及如何使用Entity Framework设置实体以使其工作。
我从后端到前端的项目如下所示:
DAL(数据访问层)
业务规则层
Web API图层
AngularJS前端
这些层中的每一个都在不同的项目中,我希望将它们分开,特别是Web API和前端,以便将来可以在不暴露业务逻辑的情况下分发API。
IDEALLY DAL图层或多或少是我的数据库E.X的实体版本。
public class BUILDING
{
public BUILDING()
{ // A List of building visitors
this.VISITORS = new HashSet<VISITOR>();
}
[key]
public int ID { get; set; }
}
public class VISITOR
{
public VISITOR() { }
[key]
public int ID { get; set; }
// The building the visitor visited
public virtual BUILDING BUILDING { get; set; }
}
DAL上方的层是业务规则,我希望处理所有逻辑和数据检查以及其他任何需要的东西。这是我开始遇到问题的地方。如果我想要一个名为ATTRACTION的业务规则对象,它包含DAL对象BUILDING和VISITOR,我将如何处理它?</ p>
public class ATTRACTION // This is the object I want Breeze to track
{
private BUILDING _building;
private List<VISITOR> _visitor;
public int Id
{
get { return _building.ID }
set { _building.ID = value; }
}
public void AddVisitor(int id)
{
// Functionality
}
}
Web API层实际上只是掩盖业务规则层并且功能很少,并且AngularJS前端已完成。
我真正遇到的麻烦是让BreezeJS使用BR层中的对象而不是DAL层。我是否以可行的方式设置数据?我知道(或至少相信)BreezeJS需要DbContext项目,但我找不到用它包装BR层对象的方法。在一天结束时,我真的只想使用BreezeJS来实现其变更跟踪功能。任何帮助都将非常受欢迎,如果需要,我可以提供更多代码示例我只想保持帖子的可管理长度。
答案 0 :(得分:1)
退后一步,问自己“客户端和服务器如何沟通?”
如果客户端向服务器发送了大量命令......“AddVisitor”,“UpdateVisitorAddress”,“GiveVisitorGoldStar”......那么你就有了一个消息传递范例。消息传递范式很好。我根本没有批评它。但是Breeze并不特别支持这种范式。
如果客户端主要执行CRUD操作 - 在实体类型上创建,读取(查询),更新和删除...那么你就得到了我称之为“实体范例”的东西。 Breeze对此有很好的支持。
我的感觉是,如果你在SQL Server前面使用EF支持的Web API ......你已经投资了实体范例。这些技术很好地支持了实体范式,消息传递范式不太好。
这个问题与在自己的层中拥有业务规则的n层后端完全不同。
DocCode example表现出类似的分离。 Web API位于“DocCode”项目中。模型层位于“DocCode.Models”项目中。数据访问层位于“DocCode.DataAccess.EF”层中。
我们可以在模型项目中放置(可能应该已经放置)验证逻辑示例代码。它恰好位于名为NorthwindEntitySaveGuard
的类中的数据访问项目中。在“现实世界”中,该类将成为模型类本身中业务逻辑的调度程序。也有一些......但并不多。
DocCode也有一些“Dtos”的例子,在一些地方很方便。
所以...已经证明你可以在服务器上进行这样的架构分离......我的问题是......你真的需要多少钱?那里有许多建筑 flim-flam ,诱使我们过度设计。
我将Web API控制器与数据访问和模型定义分开。但是我没有看到DTO舞蹈和图层层叠的重点。当然可以做到。我很怀疑它是否有所回报;它更可能让我的经历弄得一团糟。 YMMV。