如果我使用类似 NHibernate 的 ORM,为啥需要 LINQ?
Posted
技术标签:
【中文标题】如果我使用类似 NHibernate 的 ORM,为啥需要 LINQ?【英文标题】:Why do I need LINQ if I use NHibernate-like ORMs?如果我使用类似 NHibernate 的 ORM,为什么需要 LINQ? 【发布时间】:2012-01-13 09:49:05 【问题描述】:I was reading this SO question but still I am not clear about one specific thing.
如果我使用 NHibernate,为什么需要 LINQ?
当我知道 NHibernate 也包含 LINQ 支持时,我的问题变得更加严重。
LINQ to NHibernate?
WTF!
【问题讨论】:
【参考方案1】:LINQ 是一种查询 语言。它允许您以与持久层无关的方式表达查询。
您可能正在考虑LINQ 2 SQL ORM。
在命名两者时使用 LINQ 会导致像您这样不幸的混淆。
nHibernate、EF、LINQ2XML 都是 LINQ providers - 它们都允许您使用 LINQ 语法查询数据源。
【讨论】:
【参考方案2】:好吧,你不需要 Linq,你总是可以不用它,但你可能需要它。
Linq 提供了一种方法来表达对可查询的数据集执行的操作,然后我们可以根据该数据的状态执行其他操作。它是故意编写的,以便尽可能不知道该数据是否是内存中的集合、XML、数据库等。最终它总是在某种内存中的对象上运行,并通过某种方式在内存中和最终来源,尽管一些绑定比其他绑定更进一步,将一些操作向下推到不同的层。例如。调用 .Count()
最终可能会查看 Count
属性,在集合中旋转并保持计数,将 Count(*)
查询发送到数据库或其他东西。
ORM 提供了一种让内存中对象和数据库行相互反映的方法,对一个对象的更改通过对另一个对象的更改来反映。
这很适合上面的“一些转换方法”。因此,Linq2SQL、EF 和 Linq2NHibernate 都履行了 ORM 角色和 Linq 提供者角色。
考虑到 Linq 可以处理集合,你必须非常反常地创建一个根本不支持 Linq 的 ORM(你必须将集合设计为不实现 IEnumerable<T>
,因此不能使用foreach
)。更直接地支持它意味着您可以提供更好的支持。至少它应该可以进行更有效的查询。例如,如果 ORM 为我们提供了一种获取 Users
对象的方法,该对象反映了 users
表中的所有行,那么我们总是可以这样做:
int uID = (from u in Users where u.Username == "Alice" select u.ID).FirstOrDefault();
如果没有通过使Users
实现IQueryable<User>
来直接支持Linq,那么这将变成:
SELECT * FROM Users
接着是:
while(dataReader.Read())
yield return ConstructUser(dataReader);
接着是:
foreach(var user in Users)
if(user.Username == "Alice")
return user.ID;
return 0;
实际上,情况会比这差一点。在直接支持下,生成的 SQL 查询将是:
SELECT TOP 1 id FROM Users WHERE username = 'Alice'
那么C#就相当于
return dataReader.Read() ? dataReader.GetInt32(0) : 0;
应该很清楚 Linq 提供程序对内置 Linq 的更大支持应该如何带来更好的操作。
Linq 是 C# 和 VB.NET 的语言内功能,也可以被任何 .NET 语言使用,但并不总是具有相同的语言内语法。因此,任何 .NET 开发人员都应该知道它,并且每个 C# 和 VB.NET 开发人员都应该特别知道它(或者他们不知道 C# 或 VB.NET),而这正是 NHibernate 的设计目标,所以他们可以依赖于不需要通过仅以 Linq 方式实现它们来解释一大堆操作。在表示可查询数据的 .NET 库中不支持它充其量应该被视为缺乏完整性; ORM 的全部意义在于使数据库的操作尽可能接近所使用的编程语言中与数据库无关的操作。在 .NET 中,这意味着 Linq 支持。
【讨论】:
【参考方案3】:首先,LINQ 本身并不是 ORM。它是一种 DSL 来查询对象,无论其来源如何。
因此,您也可以将 LINQ 与 Nhibernate 一起使用是非常有意义的
我相信您将LINQ to SQL 误解为普通的LINQ。
【讨论】:
【参考方案4】:常识?
像 NHibernate 这样的 ORM 与表达查询的编译器集成方式之间存在差异,后者在更多场景中使用完整。
或者:LINQ 的使用(不是 LINQ to SQL 等 - 语言,虽然我不确定你的意思是什么,但你所说的语言)意味着你不必处理 Nhibernate 特殊查询语法。
或者:任何不使用 LINQ 的人——不管 NHibernate 与否——在没有充分解释的情况下被取消资格。
【讨论】:
【参考方案5】:您不需要它,但您可能会发现它很有用。请记住,正如其他人所说,Linq 与 Linq to SQL 不同。在我工作的地方,我们编写自己的 SQL 查询来检索数据,但我们经常使用 Linq 来操作该数据以满足特定需求。例如,您可能有一个数据访问方法,允许您检索 Dave 拥有的所有狗:
new DogOwnerDal().GetForOwner(id);
如果您只对 Dave 的 daschunds 有兴趣满足一个特定需求,并且性能不是什么大问题,您可以使用 Linq 将 Dave 的所有狗的响应过滤到您需要的特定数据:
new DogOwnerDal().GetForOwner(id).Where(d => d.Breed == DogBreeds.Daschund);
如果性能至关重要,您可能想要编写一个特定的数据访问方法来按所有者和品种检索狗,但在许多情况下,创建新的数据访问方法所花费的精力并不能提高效率,值得做.
在您的示例中,您可能希望使用 NHibernate 检索一组数据,然后使用 Linq 将该数据分解为许多单独的子集以进行某种形式的处理。一次获取数据并使用 Linq 将其拆分可能会更便宜,而不是重复查询数据库以获取相同数据的不同混合。
【讨论】:
以上是关于如果我使用类似 NHibernate 的 ORM,为啥需要 LINQ?的主要内容,如果未能解决你的问题,请参考以下文章
当有许多关联时使用像 NHibernate 这样的 ORM - 性能问题