DTO (linq2sql) 和 Class 对象之间的混淆!
我已经成功地使用 linq2sql 和 linq DTO(由 linq2sql 创建的类)...
我很困惑,我有更新旧应用程序的任务,我可以看到我的 DTO 将如何使用为了传输日期,
我正在使用存储库模式,因此我通过 linq2sql dtos 将数据从存储库传递到服务...一旦我处于服务层(这基本上是我的业务逻辑),那么我需要传递类对象..
这些类对象基本上是 dtos 的镜像(或多或少) - 在某些地方有一些变化,但总体上是相同的..
所以回到手头的问题! -- 仅使用 dtos 将数据从存储库传输到服务层是一个好习惯吗...一旦进入服务层(业务逻辑),我应该将所有 dtos 映射到那里的类对象对应部分(当然使用 automapper! !)
我的另一个选择是继续使用像类对象一样的 DTOS,并将它们从一个方法传递到另一个方法并作为返回类型等,但我觉得这是不好的做法,我一直在兜圈子,想知道我应该应用哪种方法?
任何帮助非常
感谢
i have been successfully working with linq2sql and the linq DTOs (the classes that are created by linq2sql) ....
I am confused, i have the task of updating an old application and i can see that my DTOs will be used how they should be .... to transport date
I am using the repository pattern so i am passing data from the repository to the service via the linq2sql dtos... once i am in the service layer (this is basically my business logic) then I need to pass around class objects ..
these class objects are basicaly a mirror image (more or less) of the dtos - there are some changes in some place but generally the same..
So getting back to the question in hand! -- is this good practice to use dtos only to transport data from repository to service layer ... and once in the service layer(business logic) i should but MAPPING all my dtos to there class object counter parts (of course using automapper!!)
My other alternative is to continue to use the DTOS like class objects and pass them around from method to method and as return types etc but i feel this is bad practice and i keep going round in circles wondering which method i should apply?
Any help really appreciated
thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是我的意见:
在处理任何重要的应用程序时。使用 linq2Sql 对象作为域模型是一个非常糟糕的主意。我将 linq2Sql 视为一个 ORM,仅此而已。数据库(linq2Sql 与之直接对应)是数据的规范化。类(在 OOAD 意义上)是行为(而非数据)的规范化。
我在使用 linq2Sql 构建应用程序时遇到了这种情况。让我们现实一点......大多数业务应用程序都是美化的 CRUD 应用程序。因此,应用程序的大部分实体将直接对应于数据库表,这并不是不可能的。 我不想直接绑定到生成的 DTO,但同时我也不希望在我的应用程序中出现重复的类。
所以这是我的解决方案:
我“编程到一个接口”。
假设我有一个
PersonDto
(Dto 代表数据传输对象),其属性为FirstName、LastName、Age
(与数据库列直接相关)。我创建了一个
IPerson
接口并让我的 PersonD 实现它。我的存储库方法将接收并检索
IPerson
而不是 Linq2Sql 类。这种方法对我来说非常有效。每当我觉得需要偏离 DTO 时,我都可以相当轻松地做到这一点,因为接口代表的是我的对象,而不是 DTO。
一些一般指示:
手动构建 DTO...我知道这听起来很疯狂,但您会发现它与自上而下、测试驱动的开发方法配合得非常好。您的 DTO (linq2Sql) 对象将非常轻,并且可以接受 .dbml 设计器之外的更改。
将 DTO 和 DataContext 保留在内部。您的 dto 没有理由公开(假设您拥有存储库和域对象的公共接口)。这样做将强制在域模型和数据访问之间进行逻辑分离。
将所有数据访问层放在一个单独的项目中(再次强制执行这种分离)。
将接口声明放在单独的项目中(这将确保您不会遇到任何循环引用)。
希望这有帮助...
Here is my opinion:
When dealing with any non-trival application. Using your linq2Sql objects as your domain model is a really bad idea. I see linq2Sql as an ORM and nothing more. Databases (which linq2Sql has a direct correspondance to) is a normalization of data. Classes (in the OOAD sense) are a normalization of behavior (not data).
I encountered this when building applications with linq2Sql. Lets be realistic....most line of business applications are glorified CRUD applications. So it isn't out of the question that a large percentage of your application's entities will correspond directly to database tables. I didn't want to be bound directly to the DTO's that were generated, but at the same time I didn't want duplicated classes littered across my application.
So here is my solution:
I "programmed to an interface".
Lets say I have a
PersonDto
(Dto standing for Data Transfer Object) with properties ofFirstName, LastName, Age
(which relate directly to database columns).I created an
IPerson
interface and had my PersonDto implement it.And my repository method would take in and retrieve
IPerson
as opposed to the Linq2Sql class.This approach has worked really well for me. Whenever I feel I need to deviate from the DTO, I can do so fairly easily because of the interface representing my object as opposed to the DTO.
Some general pointers:
Build your DTO's by hand...I know it sounds crazy, but you'll find that it works really well with a top down, test driven development approach. Your DTO's (linq2Sql) objects will be extremely light and will be open to changes outside of the .dbml designer.
Keep your DTO's and DataContext's internal. There is no reason for your dto's to be exposed publicly (given that you have public interfaces for you repositories and domain objects). Doing this will force a logical separation between your domain model and data access.
Put all of your data access layer in a separate project (again to enforce this separation).
Put your interface declarations in a separate project (this will ensure you don't run into any circular references).
Hope this helps...
我实际上对这个主题有类似的问题,尽管我的意图略有不同。建议使用 Linq2SQL 类作为域对象,并利用其他人提到的部分类。我主要关心的是这些对象的形状(即属性名称)以及类成员的可访问性(例如私有与受保护)。
对象的形状甚至可访问性都可以通过使用 t4 模板来解决,其中 Damien Guard 组合了一个 T4 模板,以允许您控制 Linq2Sql 将为您生成的类的形状。这可以在这里看到 T4 Linq2SQL 的模板。
这就是我要研究的方法,看看它是否能解决我的担忧。此外,如果您的服务层可以接受方法参数的接口,您还可以通过 Linq2SQL DTO 周围的接口包装器来控制服务层可以访问的内容。
希望这有帮助。
I actually had a similar question on this topic although my intent was slightly different. The recommendation was to use the Linq2SQL classes as the domain objects and to take advantage of partial classes as others have mentioned. My main concern came with the shape of those objects (ie property names), and the accessibility of class members (ie private v.s. protected for example).
The shape of the objects and even the accessibility can be addressed by using t4 templates where Damien Guard has put together a T4 template to allow you to control the shape of the classes that Linq2Sql would generate for you. This can be seen here T4 template for Linq2SQL.
This is the approach that I am going to look into and see if it addresses my concerns. Additionally if your service layer can accept interfaces to method arguments you can also control what the service layer has access to through interface wrappers around your Linq2SQL DTOs.
Hope this helps.
这是我见过的关于该主题的最佳讨论之一:
http://blog.wekeroad.com/blog/linqtosql-momma-said-knock-you-out/
最后,耦合和内聚决策是视情况而定的,您必须决定什么是最适合的你的情况。
当您的应用程序无法满足 LinqToSql 的需求时,取出 LinqToSql 并在其位置插入另一个 ORM 有多容易?这是你必须认真考虑的事情。
一般来说,尽量减少业务层对 LinqToSql 的了解。 LinqToSql 应该对您的 UI 层完全隐藏(您的业务层构成了这个盾牌的很大一部分)。使用 LinqToSql 很容易走上错误的架构道路,并且事后很难回到正确的道路上。
This is one of the best discussions of the topic that I've seen:
http://blog.wekeroad.com/blog/linqtosql-momma-said-knock-you-out/
In the end, coupling and cohesion decisions are situational and you have to decide what is best for your situation.
When your application outgrows LinqToSql, how easy will it be to yank out LinqToSql and insert another ORM in it's place? That is something you have to give serious thought to.
In general, minimize the knowledge your business layer has about LinqToSql. LinqToSql should be completely hidden from your UI layer (your business layer makes up a good chunk of this shield). It's very easy to go down the wrong architectual path with LinqToSql and it can be very difficult to get back on the right path after the fact.
linq2sql 设计器生成的类是部分类,因此您可以扩展它们并将业务逻辑直接放入其中。这个想法是 linq 用于持久/重建这些实体,这样您就可以避免您正在谈论的那种映射。
The classes generated by the linq2sql designer are partial classes, so you can extend these and put your business logic directly into them. The idea is that linq is used to persist/reconstruct these entities so you can avoid the kind of mapping you're talking about.