我知道围绕这个主题有很多线索,但我没有找到任何让我满意的帖子,也没有真正解释如何在实体框架内开发业务逻辑。因此,在这篇文章中,我想总结一下我通过阅读其他各种帖子得到了什么,然后请你帮助我清理我的头脑。
实体:--这些是我的类--映射到数据库中的表,如User、Transaction、Order等等。这些是POCO对象(我将它们与代码第一方法一起使用)。
域模型:--这是业务逻辑应该出现的地方。我花了很长一段时间才发现,领域模型并不是EF的同义词。
Service-Layer: --我发现,首先不需要服务层。它可以用来给它带来一些东西,但是在一般情况下,业务逻辑应该在模型中。所以最好把它放出来
Repository-Layer: Ok --我们可以用CRUD方法编写一个存储库,比如IEnumerable GetUsers(),这样可以简化测试,但另一方面,我们将失去整个LINQ特性,而且编写起来要多得多。为了进行测试,我还可以模拟EF框架,因此对于我来说,存储库层已经过时了。
Unit-Of-Work: DbContext本身就是一个工作单元.因此,我不必在这里编写任何特殊的代码,只需将DbContext传递给我的所有方法,并在完成时调用SaveChanges。
Lazy-Loading:有时我确实使用它,有时我确实使用Eage加载。但在此期间,我发现,当您想要完成工作单元和保持代码整洁时,延迟加载是必须的。当您在一个方法中,并得到一些代码传递到它是从另一个方法,而反过来从另一个方法.你只想访问这些属性。你不会在乎数据是否在里面。它必须自动加载。因此,我想知道如何做到这一点,而没有任何懒散的加载。
DbContextScopes:就像在其他文章中讨论的那样,我们不应该在应用程序实例上使用DbContext,也不应该在每个请求中使用它。相反,我们应该为当前任务创建一个DbContext,并将其传递给所有需要的方法。使用DbContextScopeFactory可以使这更容易。
依赖项注入:--我总是应该使用DI在构造函数中注入所需的东西。这是有意义的,因为当我们有一个单元测试,我们可以只是放在模拟资源。我还读到属性注入不是很好,不应该使用。
Transactions:不应该再使用了,因为它们有很多问题。相反,坚持工作单元(在内部使用事务?!)然后用这种方式来建模你的架构。
所以现在我想知道怎样才能真正使用这些东西。
问题1:模型=实体?
我们应该创建某种独立的域模型,还是将其包含在实体模型中?我认为,对于很多代码来说,一个额外的域模型似乎是可行的。为什么不将逻辑写入实体中呢?有什么问题吗?
问题2:如何获得DbContext?
当我添加一个实体时,我不想添加基础设施,比如
order.Lines.Add(new OrderLine(product, qty, text));而不是
order.Lines.Add(new OrderLine(dbcontext, product, qty, text));也许属性依赖注入是一种解决方案,但正如所说的,这也不是一个好的模式.
发布于 2015-07-29 16:01:13
问题1
您的域模型应该表示您的数据库,并且在将数据轻松地从数据库传输到应用程序的任何部分方面应该是干净和轻巧的。如果您将逻辑添加到您的模型中,它们很快就会变得臃肿和沉重,因此每次您重新建立每个域模型的实例时,您的逻辑都会与它一起出现,不管它是否会被使用!
如果您开始将所有的逻辑都放入域模型中,您很快就会意识到您想要访问其他域模型的属性,然后必须开始将它们相互传递,很快就会变得一团糟。它唯一有用的地方是,您只编写过一次代码,但这正是将逻辑分离成服务层的好处显而易见的地方。
有一个服务层的好处是,每个服务都可以包含在DTO和(轻量级)域模型上执行特定功能或函数组的逻辑,它们只需要编写一次,相同的代码可以在整个应用程序中多次使用。您可以将服务接口出来,并在需要时将每个服务作为依赖项添加到控制器中,以便只将它们公开到每个控制器实际需要的服务中的逻辑的特定部分,而不再暴露给以前可能已写入域模型的每个逻辑段。
拥有一个服务层也会显著减少控制器中的代码数量,因为您的业务逻辑将在您的服务中执行,控制器操作只会将值传递给您的服务以进行处理,并将它们映射回您的视图模型。
问题2
根据您正在做的事情(如果您没有在请求中使用多个线程),通常每个HTTP请求都应该有一个新的DbContext --这可以使用大多数DI容器进行配置。我会在您的MVC应用程序层中配置DbContext并将其向上注入服务层。
..。
https://stackoverflow.com/questions/31703585
复制相似问题