如何摆脱 ORM 的限制或者应该避免它们?
简而言之,像实体框架这样的 ORM 提供了一种快速的解决方案,但有很多限制,什么时候应该避免它们(ORM)?
我想创建一个DMS系统的引擎,我想知道如何创建业务逻辑层。
我将讨论以下选项:
使用实体框架并稍后将其作为业务提供给引擎的客户。
问题是缺少对属性和验证的控制,因为它是生成的代码。
手动创建我自己的业务层类,而不使用实体框架或任何 ORM:
问题是,这是一项艰巨的任务,就像重新发明 Weel 一样。
在实体框架上创建我自己的业务层类(使用它)
问题似乎是通过创建具有相同名称的新类来重复代码,并且每个属性都将覆盖 ORM 生成的相反属性。
我是否以正确的方式讨论问题?
In short, ORMs like Entity Framework provides a fast solution but with many limitations, When should they (ORMs) be avoided?
I want to create an engine of a DMS system, I wonder that how could I create the Business Logic Layer.
I'll discuss the following options:
Using Entity Framework and provides it as a Business later for the engine's clients.
The problem is that missing the control on the properties and the validation because it's generated code.
Create my own business layer classes manually without using Entity Framework or any ORM:
The problem is that it's a hard mission and something like reinvent the weel.
Create my own business layer classes up on the Entitiy Framework (use it)
The problem Seems to be code repeating by creating new classes with the same names and every property will cover the opposite one which is generated by the ORM.
Am I discuss the problem in a right way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
简而言之,在以下情况下应避免 ORM:
您的程序将执行批量插入/更新/删除(例如插入选择和以非唯一条件为条件的更新/删除)。 ORM 的设计初衷并不是为了有效地执行此类批量操作;您最终将一次删除一条记录。
您正在使用高度自定义的数据类型或转换。 ORM 通常不擅长处理 BLOB,并且如何告诉它们如何“映射”对象也存在限制。
您需要在与 SQL Server 的通信中获得绝对最高的性能。 ORM 可能会遇到 N+1 问题和其他查询效率低下的问题,总体而言,它们在对象请求和 SQL 语句之间添加了一层(通常是反射性)转换,这会减慢您的速度。
ORM 应在大多数基于应用程序的记录维护情况下使用,其中用户正在查看聚合结果和/或更新由简单数据类型组成的单个记录,一次一个。与原始 SQL 相比,ORM 具有极大的优势,能够使用 Linq 提供程序提供经过编译器检查的查询;几乎所有流行的 ORM(Linq2SQL、EF、NHibernate、Azure)都有一个 Linq 查询接口,可以捕获大量“胖手指”和查询中的其他常见错误,而这些错误在使用“魔术字符串”形成时无法捕获SQL命令。 ORM 通常还提供数据库独立性。经典的 NHibernate HBM 映射是 XML 文件,可以根据需要进行交换,以将存储库指向 MSS、Oracle、SQLite、Postgres 和其他 RDBMS。如果架构正确,即使是“流畅”映射(代码文件中的类)也可以被交换。 EF 具有类似的功能。
In short, ORMs should be avoided when:
your program will perform bulk inserts/updates/deletes (such as insert-selects, and updates/deletes that are conditional on something non-unique). ORMs are not designed to do these kinds of bulk operations efficiently; you will end up deleting each record one at a time.
you are using highly custom data types or conversions. ORMs are generally bad at dealing with BLOBs, and there are limits to how they can be told how to "map" objects.
you need the absolute highest performance in your communication with SQL Server. ORMs can suffer from N+1 problems and other query inefficiencies, and overall they add a layer of (usually reflective) translation between your request for an object and a SQL statement which will slow you down.
ORMs should instead be used in most cases of application-based record maintenance, where the user is viewing aggregated results and/or updating individual records, consisting of simple data types, one at a time. ORMs have the extreme advantage over raw SQL in their ability to provide compiler-checked queries using Linq providers; virtually all of the popular ORMs (Linq2SQL, EF, NHibernate, Azure) have a Linq query interface that can catch a lot of "fat fingers" and other common mistakes in queries that you don't catch when using "magic strings" to form SQLCommands. ORMs also generally provide database independence. Classic NHibernate HBM mappings are XML files, which can be swapped out as necessary to point the repository at MSS, Oracle, SQLite, Postgres, and other RDBMSes. Even "fluent" mappings, which are classes in code files, can be swapped out if correctly architected. EF has similar functionality.
那么你是在问如何在不做“X”的情况下做“X”吗? ORM 是一种抽象,与任何其他抽象一样,它也有缺点,但不是你提到的那些。
So are you asking how to do "X" without doing "X"? ORM is an abstraction and as any other abstraction it has disadvantages but not those you mentioned.
免责声明:我在 Mindscape 工作,为 .NET 构建 LightSpeed ORM,
因为您没有询问具体问题,而是询问使用 ORM 解决灵活性问题的方法,我想我应该插话一下从供应商的角度来看一些观点。它可能对您有用,也可能没用,但可能会给您带来一些思考:-)
在设计 O/R 映射器时,考虑我们所说的“逃生舱口”非常重要。 ORM 将不可避免地推动一组特定的默认行为,这是开发人员提高生产力的一种方式。
我们从 LightSpeed 中学到的教训之一是开发人员需要这些逃生舱口。例如,KeithS 在此指出 ORM 不适合批量操作 - 在大多数情况下确实如此。我们为一些客户提出了这种方案,并向我们的Remove() 操作添加了一个重载,该操作允许您传入一个删除所有匹配记录的查询。这节省了将实体加载到内存中并删除它们的麻烦。倾听开发人员的痛点并帮助快速解决这些问题对于帮助构建可靠的解决方案非常重要。
所有 ORM 都应该有效地批量查询。话虽如此,我们惊讶地发现许多 ORM 不这样做。这很奇怪,因为批处理通常可以相当容易地完成,并且可以将多个查询捆绑在一起并立即发送到数据库以节省往返次数。这是我们从第一天起就为任何支持它的数据库所做的事情。这只是本线程中批处理的一点旁白。这些批量查询的质量是真正的挑战,坦率地说,某些 ORM 生成了一些糟糕的 SQL 语句。
总体而言,您应该选择一个能够立即提高生产力的 ORM(几乎是演示软件,“看我在 30 秒内查询了数据!”),但也关注更大规模的解决方案,这是逃生舱口和一些不太演示的地方,但是需要非常有用的功能。
我希望这篇文章不会显得过于推销,但我想提醒大家在选择产品时考虑到任何产品背后的思维过程。如果理念符合您需要的工作方式,那么您可能会比选择不符合的理念更快乐。
如果您有兴趣,可以了解我们的LightSpeed ORM for .NET。
Disclaimer: I work at Mindscape that builds the LightSpeed ORM for .NET
As you don't ask about a specific issue, but about approaches to solving the flexibility problem with an ORM I thought I'd chime in with some views from a vendor perspective. It may or may not be of use to you but might give some food for thought :-)
When designing an O/R Mapper it's important to take into consideration what we call "escape hatches". An ORM will inevitably push a certain set of default behaviours which is one way that developer gain productivity gains.
One of the lessons we have learned with LightSpeed has been where developers need those escape hatches. For example, KeithS here states that ORMs are not good for bulk operations - and in most cases this is true. We had this scenario come up with some customers and added an overload to our Remove() operation that allowed you to pass in a query that removes all records that match. This saved having to load entities into memory and delete them. Listening to where developers are having pain and helping solve those problems quickly is important for helping build solid solutions.
All ORMs should efficiently batch queries. Having said that, we have been surprised to see that many ORMs don't. This is strange given that often batching can be done rather easily and several queries can be bundled up and sent to the database at once to save round trips. This is something we've done since day 1 for any database that supports it. That's just an aside to the point of batching made in this thread. The quality of those batches queries is the real challenge and, frankly, there are some TERRIBLE SQL statements being generated by some ORMs.
Overall you should select an ORM that gives you immediate productivity gains (almost demo-ware styled 'see I queried data in 30s!') but has also paid attention to larger scale solutions which is where escape hatches and some of the less demoed, but hugely useful features are needed.
I hope this post hasn't come across too salesy, but I wanted to draw attention to taking into account the thought process that goes behind any product when selecting it. If the philosophy matches the way you need to work then you're probably going to be happier than selecting one that does not.
If you're interested, you can learn about our LightSpeed ORM for .NET.
根据我的经验,当您的应用程序执行以下数据操作时,您应该避免使用 ORM:
1)批量删除:大多数 ORM 工具不会真正删除数据,它们会用垃圾收集 ID(GC 记录)对其进行标记以保留数据库一致性。最糟糕的是 ORM 在将数据标记为已删除之前收集了您想要删除的所有数据。这意味着,如果您想删除 1000000 行,ORM 将首先获取数据,将其加载到您的应用程序中,将其标记为 GC,然后更新数据库;。我相信这是一笔巨大的资源。
2)批量插入和数据导入:大多数ORM工具都会在业务类上创建业务层验证,如果您想验证1条记录,那么这很好,但如果您要插入/导入数百甚至数百万条记录,则该过程可能需要几天时间。
3)报告生成:ORM 工具非常适合创建简单的列表报告或简单的表连接,例如在 order-order_details 场景中。但在大多数情况下,ORM 只会减慢数据的检索速度,并且会添加报告所需的更多联接。与通常使用 SQL 方法相比,这会给数据库引擎带来更多的工作
in my experience you should avoid use ORM when your application do the following data manipulation:
1)Bulk deletes: most of the ORM tools wont truly delete the data, they will mark it with a garbage collect ID (GC record) to keep the database consistency. The worst thing is that the ORM collect all the data you want to delete before it mark it as deleted. That means that if you want to delete 1000000 rows the ORM will first fetch the data, load it in your application, mark it as GC and then update the database;. which I believe is a huge waist of resources.
2)bulk inserts and data import:most of the ORM tools will create business layer validations on the business classes, this is good if you want to validate 1 record but if you are going to insert/import hundreds or even millions of records the process could take days.
3)Report generation: the ORM tools are good to create simple list reports or simple table joins like in a order-order_details scenario. but it most cases the ORM will only slow down the retrieve of the data and will add more joins that you need for a report. that translate in a give more work to the DB engine than you usually do with a SQL approach