简体   繁体   English

在Linq to SQL中重写NHibernate应用程序

[英]Rewriting NHibernate app in Linq to SQL

I have an old outdated application written using NHibernate. 我有一个使用NHibernate编写的旧的过时应用程序。 Now I would like to rewrite it including new functionality and big changes in model. 现在我想重写它,包括新功能和模型的重大变化。

What are main disadvantages of using Linq to SQL instead of NHibernate ? 使用Linq to SQL而不是NHibernate的主要缺点是什么?

What are possible problems of using LINQ to SQL, does making DataContext as something like singleton can give poor performance? 使用LINQ to SQL可能存在哪些问题,是否使得DataContext像singleton一样会导致性能不佳?

From "The false myth of encapsulating data access in the DAL" : “在DAL中封装数据访问的错误神话”

"I would like to design a system/application using NHibernate. But I also want to so flexible that in future ,if I unplug the NHibernate and use ADO.NET Entity framework or other framework then my application should not crash." “我想使用NHibernate设计一个系统/应用程序。但是我也想要如此灵活,以后如果我拔掉NHibernate并使用ADO.NET Entity框架或其他框架,那么我的应用程序不应该崩溃。”

In short, I am completely opposed for even trying doing something like that. 简而言之,我甚至完全反对尝试这样的事情。

It is based on flawed assumptions 它基于有缺陷的假设

A lot of the drive behind this is based on the historical drive built in the time where data access layers directly accessed a database using its own dialect, resulting in the need to create just such an encapsulation in order to support multiple databases. 这背后的许多驱动力是基于在数据访问层使用自己的方言直接访问数据库的时间内构建的历史驱动器,导致需要创建这样的封装以支持多个数据库。

The issue with this drive is that it is no longer a factor, all modern OR/Ms can handle multiple databases effectively. 这个驱动器的问题在于它不再是一个因素,所有现代OR / Ms都可以有效地处理多个数据库。 Moreover, modern OR/M are no longer just ways to execute some SQL and get a result back, which is how old style DAL were written. 而且,现代OR / M不再仅仅是执行某些SQL并获得结果的方法,这就是DAL的旧式写法。 An OR/M takes on a lot more responsibilities, from things like change tracking to cache management, from ensuring optimistic concurrency to managing optimal communication with the database. OR / M承担更多责任,从更改跟踪到缓存管理,从确保乐观并发到管理与数据库的最佳通信。

And those features matter, a lot. 这些功能很重要。 Not only that, but they are different between each OR/M. 不仅如此,它们在每个OR / M之间也不同。

It doesn't work, and you'll find that out too late 它不起作用,你会发现它太晚了

The main problem is that no matter how hard you try, there are going to be subtle and not so subtle differences between different OR/Ms, those changes can drastically affect how you build your application. 主要的问题是,无论你怎么努力,不同的OR / Ms之间都会有微妙而不那么微妙的差异,这些变化会极大地影响你构建应用程序的方式。

So how do you move between OR/Ms? 那么你如何在OR / Ms之间移动?

There are reasons why some people want to move from one data access technology to the other. 有些人希望从一种数据访问技术转移到另一种数据访问技术。 I was involved in several such efforts, and the approach that we used in each of those cases was porting , rather than trying to drop a new IDataAccess implementation. 我参与了几个这样的工作,我们在每个案例中使用的方法是移植 ,而不是试图删除新的IDataAccess实现。

Huge question but one thing that I was made aware of during a large refactor from L2S to NHibernate 2.x is that NHibernate allows for a base class to be represented in a different physical table than the derivative. 很大的问题,但是我在L2S到NHibernate 2.x的大型重构中意识到的一件事是,NHibernate允许基类在不同的物理表中表示而不是衍生物。 But with L2S I was forced to use 1 single table to represent the base and each class that would extend it. 但是对于L2S,我被迫使用1个单独的表来表示基础,并且每个类都会扩展它。

This allowed me to create smaller tables because I had a base class that was inherited by about 25 different variations of child classes. 这允许我创建更小的表,因为我有一个基类,它由大约25种不同的子类变体继承。 If you would like to use this functionality going forward it could help simplify your schema. 如果您希望继续使用此功能,它可以帮助简化您的架构。

What are main dissadvantages of using Linq to SQL instead of NHibernate ? 使用Linq to SQL而不是NHibernate的主要缺点是什么?

Advantages of LINQ to SQL LINQ to SQL的优点

  • More advanced and easier to use (IMHO) querying syntax, specifically it uses LINQ to perform queries, which give you strongly typed/compile time safe queries. 更高级和更易于使用(IMHO)查询语法,特别是它使用LINQ执行查询,这为您提供强类型/编译时安全查询。 NHibernate gives you HQL, which although quite powerful, is all string based. NHibernate为您提供了HQL,虽然它非常强大,但它都是基于字符串的。 NHibernate also has Criteria queries which a bit more strongly typed (still some strings), but it's syntax/API is quite difficult to get one's head around. NHibernate还有一些Criteria查询,它有点强类型(仍然是一些字符串),但它的语法/ API很难让人知道。

NHibernate v2 does have a LINQ provider you can download, but it's a bit lacking (a lot lacking in fact), plenty of use cases it doesn't support. NHibernate v2确实有一个你可以下载的LINQ提供程序,但它有点缺乏(事实上很多缺乏),它不支持大量的用例。 NHibernate 3.0 comes with it's own built in LINQ provider which is much more powerful, almost up to par with LINQ 2 SQL or EF. NHibernate 3.0附带了自己的内置LINQ提供程序,它功能更强大,几乎与LINQ 2 SQL或EF相当。


Disadvantages with LINQ to SQL LINQ to SQL的缺点

Just about EVERYTHING else! 几乎所有其他的! Seriously where do I start: 说真的从哪里开始:

  • Simple Table to entity mapping , unlike NHibernate which has more powerful mapping capabilities including: Unidirectional associations, component mapping, you can map collections of value types such as public IList<string> Tags {get; set; } 简单表到实体映射,不像NHibernate,它具有更强大的映射功能,包括:单向关联,组件映射,您可以映射值类型的集合,例如public IList<string> Tags {get; set; } public IList<string> Tags {get; set; } public IList<string> Tags {get; set; } , inheritance mapping (very powerful), Enum mapping, plus more... public IList<string> Tags {get; set; } ,继承映射(非常强大),枚举映射,还有更多......

  • Your entities become tightly coupled to LINQ to SQL, which can effect unit testing. 您的实体与LINQ to SQL紧密耦合,从而影响单元测试。 NHibernate supports POCO mapping, important for implementing loosely coupled, maintainable, unit testable code base. NHibernate支持POCO映射,这对于实现松散耦合,可维护,可单元测试的代码库非常重要。

  • Supports more databases (SQL Server, MySql, PostgreSQL, Oracle, SQLite, + more). 支持更多数据库(SQL Server,MySql,PostgreSQL,Oracle,SQLite,+更多)。 LINQ 2 SQL only supports MS SQL Server. LINQ 2 SQL仅支持MS SQL Server。

  • Ability to implement DDD (Domain Driven Design) principles in your application with NHibernate. 能够使用NHibernate在您的应用程序中实现DDD(域驱动设计)原则。 LINQ 2 SQL is more of a database centric view of your domain model, whereas NHibernate takes a more business/behaviour centric view of your domain. LINQ 2 SQL更像是域模型的以数据库为中心的视图,而NHibernate则以域的更多业务/行为为中心。

Seriously, taking an NHibernate application and 'downgrading' it to LINQ 2 SQL seems like a step backwards. 说真的,采用NHibernate应用程序并将其“降级”为LINQ 2 SQL似乎是倒退了一步。 If you want to use something more Microsofty at least consider using Entity Framework 4.0. 如果你想使用更多的微软,至少考虑使用Entity Framework 4.0。 LINQ 2 SQL has it's place with simpler applications with only a few tables, but anything more complicated needs a more powerful ORM. LINQ 2 SQL拥有更简单的应用程序,只有几个表,但更复杂的东西需要更强大的ORM。

When I'm building an app, and it has a simple domain, and a basic schema, I love Linq2Sql. 当我正在构建一个应用程序,它有一个简单的域和一个基本架构时,我喜欢Linq2Sql。 Linq is quick to write, and I can get things done quickly. Linq写得很快,我可以快速完成任务。 I realize there is a Linq2NHibernate out there, but I'm not sure what the maturity of it is. 我意识到那里有一个Linq2NHibernate,但我不确定它的成熟度是多少。 Some downsides, IMO to Linq2Sql are having to regenerate classes and the DataContext whenever the schema changes, and having to map from Linq2Sql generated classes, into my domain objects. 一些缺点,IMO到Linq2Sql必须在架构更改时重新生成类和DataContext,并且必须从Linq2Sql生成的类映射到我的域对象。 For small easy projects, I really don't mind doing this. 对于小型简易项目,我真的不介意这样做。 Though with FluentNHibernate, and Linq2NHibernate, I might be able to be just as efficient with NHibernate as with Linq2Sql, but I haven't tried. 虽然使用FluentNHibernate和Linq2NHibernate,但我可能能够像使用Linq2Sql一样高效地使用NHibernate,但我还没有尝试过。

I was on a project that was using Linq2Sql on an over-normalized database with a somewhat complex domain, and it was a nightmare. 我在一个项目上使用Linq2Sql在过度规范化的数据库上使用了一个有点复杂的域,这是一场噩梦。 It worked, and we were able to wrestle some good performance out of it, but the maintainability was almost non-existent. 它起作用了,我们能够从中获得一些好的表现,但可维护性几乎不存在。 But with the schema the way it was, I'm not sure NHibernate, or straight SQL would have changed that. 但是对于架构的方式,我不确定NHibernate,或者直接SQL会改变它。 This is one case where without a doubt in my mind, a Document Database would have been the way to go. 这是一个毫无疑问的案例,文档数据库应该是可行的方法。

If the project was already done with NHibernate, and you have that experience, I would stick with it. 如果该项目已经完成了NHibernate,并且你有这种经验,我会坚持下去。 The fact that you can map directly to your domain objects is great. 您可以直接映射到域对象的事实很棒。 Linq2Sql code generation can be a pain when the schema is changing early in development. 当架构在开发早期发生变化时,Linq2Sql代码生成可能会很痛苦。 On top of that, Linq2Sql is effectively dead. 最重要的是,Linq2Sql实际上已经死了。 MS is putting all of its ORM eggs in the Entity Framework basket. MS将其所有ORM蛋放入实体框架篮子中。

Rather than doing a full port, maybe all you need is to LINQ-ify your NHibernate layer... 你可能只需要LINQ-ify你的NHibernate层,而不是做一个完整的端口......

http://www.hookedonlinq.com/LINQToNHibernate.ashx http://www.hookedonlinq.com/LINQToNHibernate.ashx

Some additional reading material: 一些额外的阅读材料:

http://www.caffeinatedcoder.com/linq-to-nhibernate/ http://www.caffeinatedcoder.com/linq-to-nhibernate/

Quote: 引用:

Thanks to the new NHibernate LINQ provider, I can now work in a mode that is not only more type safe, but also much more readable. 感谢新的NHibernate LINQ提供程序,我现在可以在一种不仅更安全,更可读的模式下工作。

Look at these before and after queries and judge for yourself: 在查询之前和之后查看这些并自行判断:

Before (Criterion API) 之前(Criterion API)

   1: public IList<Call> GetCallsByDate(DateTime beginDate, int interpreterId)
   2: {
   3:     ICriteria criteria = Session.CreateCriteria(typeof(Call))
   4:         .CreateAlias("Customer", "Customer")
   5:         .Add(Restrictions.Gt("StartTime", beginDate))
   6:         .Add(
   7:            Restrictions.Or(
   8:                 Restrictions.Lt("EndTime", DateTime.Now), Restrictions.IsNull("EndTime")
   9:                 )
  10:             )
  11:         .Add(Restrictions.Eq("Interpreter.Id", interpreterId))
  12:         .AddOrder(Order.Desc("StartTime"))
  13:         .AddOrder(Order.Desc("Customer.Name"));
  14:
  15:     return criteria.List<Call>() as List<Call>;
  16: }

After (LINQ to NHibernate) 之后(LINQ to NHibernate)

   1: public IList<Call> GetCallsByDateWithLinq(DateTime beginDate, int interpreterId)
   2: {
   3:     var query = from call in Session.Linq<Call>()
   4:                     where call.StartTime > beginDate
   5:                         && (call.EndTime == null || call.EndTime < DateTime.Now )
   6:                         && call.Interpreter.Id == interpreterId
   7:                     orderby call.StartTime descending, call.Customer.Name
   8:                     select call;
   9:
  10:     return query.ToList();
  11: }

if i remember correctly Linq2Sql does not support Many to Many table relationships nicely 如果我没记错,Linq2Sql不能很好地支持多对多的表关系

http://www.chrisbrandsma.com/2007/08/linq-to-sql-many-to-many-tables-and.html http://www.chrisbrandsma.com/2007/08/linq-to-sql-many-to-many-tables-and.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM