我都快疯了。EF给我们带来了非常方便的发展经验。
但是,如果需要在上层使用实体模型,则通常会从上层引用DAL或在包含实体类的较低层添加一个引用。我把情况想象出来了。
+-------------------+
| |
| Presentation |
(This layer is directly referring to DAL, which break the 3-tier architecture rules)
+-------------------+
|
|
|
|
+---------v---------+
| |
| BLL |
(Function that returning Entity Model)
+-------------------+
|
|
|
|
+---------v---------+
| |
| DAL |
(Repo & Entity Model)
+-------------------+在BLL上实现像DTO这样的东西是相当沉重的,不能完全解决这个问题。因此,我可能不会尝试在这样的层实现DTO。
同时,我发现一些项目可能会删除那些Entity Model,如下图所示。这是解决问题的好办法吗?
+-------------------+
| |
+------------------+ Presentation |
| | |
| +---------+---------+
| |
| |
| |
| |
+-----v------+ +---------v---------+
| | | |
| Entities <-----------+ BLL |
| | (Function that returning Entity Model)
+-----^------+ +---------+---------+
| |
| |
| |
| |
| +---------v---------+
| | |
+------------------+ DAL |
| (Repositories) |
+-------------------+虽然这个设计可以解决一些问题,但是开发人员可以尝试通过调用Presentation Layer将实体更新为DB。太危险了。如何防止其他开发人员在上层调用SaveChanges()?
发布于 2018-10-25 15:25:20
如何防止其他开发人员在上层调用saveChanges()?
唯一明智的方法是执行层间的真正分离,而唯一合理的方法是在interface /BLL接口上维护您自己的数据传输对象集(DTO),这就违背了使用实体框架的目的。
我给你看点东西。
在我以前的工作中,我们使用了实体框架,但是除了引用实体类之外,我们从未调用SaveChanges()或使用DBContext对象。相反,我们使用了裸查询。
using (var context = new CustomerContext())
{
var customer = context.Database.SqlQuery(
"SELECT * FROM Customers WHERE CustomerID = {0}", customerID).FirstOrDefault();
}随着时间的推移,我们开始放弃使用EF生成的DTO,而只是开始创建我们自己的DTO。裸查询不需要EF放入DTO的所有机器,比如更改跟踪,您可以为特定的查询定制每个DTO。
这听起来好像我们正在承担实体框架已经为您做的大量工作,但是它带来了一些显著的好处:
在我目前的工作中,我继承了这种技术,但是用Dapper取代了实体框架,Dapper是Stack Exchange使用的微ORM。这些查询看起来几乎与上面的查询一模一样。我使用这个工具生成实体类。
Dapper的好处是它包含CRUD扩展,包括更改跟踪。您只需调用受影响实体的Update()即可。区别在于,如果愿意,现在可以将Update方法隐藏在表示层中;只需放弃Dapper使用的IDbConnection对象即可。
https://softwareengineering.stackexchange.com/questions/380547
复制相似问题