C# 如果我像ORMs一样使用NHibernate,为什么我需要LINQ?

C# 如果我像ORMs一样使用NHibernate,为什么我需要LINQ?,c#,linq,nhibernate,orm,C#,Linq,Nhibernate,Orm,如果我使用NHibernate,为什么我需要LINQ 当我知道NHibernate也包括LINQ支持时,我心中的问题变得更加严重 林克到尼伯内特 WTF 是一种查询语言。它允许您以一种与持久性层无关的方式表达查询 你可能在想这个问题 使用LINQ来命名这两个词会导致像您这样的不幸混淆 nHibernate、EF、LINQ2XML都是—它们都允许您使用LINQ语法查询数据源。常识 像NHibernate这样的ORM和编译器集成的表达查询的方式之间有一个区别,这种方式在更多的场景中被完全使用 或者:

如果我使用NHibernate,为什么我需要LINQ

当我知道NHibernate也包括LINQ支持时,我心中的问题变得更加严重

林克到尼伯内特

WTF

是一种查询语言。它允许您以一种与持久性层无关的方式表达查询

你可能在想这个问题

使用LINQ来命名这两个词会导致像您这样的不幸混淆

nHibernate、EF、LINQ2XML都是—它们都允许您使用LINQ语法查询数据源。

常识

像NHibernate这样的ORM和编译器集成的表达查询的方式之间有一个区别,这种方式在更多的场景中被完全使用

或者:使用LINQ(不是LINQ到SQL等等——语言,这就是你所说的,尽管我不确定你的意思是什么)意味着你不必处理Nhibernate特殊查询语法


或者:任何不使用LINQ的人——无论是否使用NHibernate——都会在没有很好解释的情况下被取消资格。

首先,LINQ本身并不是ORM。它是一种DSL,用于查询对象,而不考虑其来源

因此,您也可以将LINQ与Nhibernate一起使用,这是非常合理的

我相信你误解了平原的意思。

你不需要它,但你可能会发现它很有用。请记住,正如其他人所说,Linq与LINQtoSQL不是一回事。在我工作的地方,我们编写自己的SQL查询来检索数据,但我们通常使用Linq来处理数据,以满足特定的需要。例如,您可能有一个数据访问方法,允许您检索Dave拥有的所有狗:

new DogOwnerDal().GetForOwner(id);
如果您只对Dave的daschunds感兴趣,只是为了满足一个特定的需求,而性能并不是一个很大的问题,那么您可以使用Linq将Dave的所有狗的响应过滤到您需要的特定数据:

new DogOwnerDal().GetForOwner(id).Where(d => d.Breed == DogBreeds.Daschund);
如果性能至关重要,那么您可能希望编写一个特定的数据访问方法来按狗主和品种检索狗,但在许多情况下,创建新的数据访问方法所花费的精力并没有提高足够的效率


在您的示例中,您可能希望使用NHibernate检索一块数据,然后使用Linq将该数据分解为许多单独的子集,以进行某种形式的处理。一次获取数据并使用Linq将其拆分可能更便宜,而不是重复询问数据库中相同数据的不同混合。

好吧,你不需要Linq,你可以不用它,但你可能需要它

Linq提供了一种表示操作的方法,这些操作在可以查询的数据集上进行,然后我们可以根据该数据的状态执行其他操作。它是故意编写的,以便尽可能不可知数据是否在内存集合、XML、数据库等中。最终,它总是在某种内存对象上运行,通过某种方式在内存和最终源之间转换,尽管有些绑定比其他绑定更进一步,将某些操作下推到另一层。例如,调用
.Count()
可以查看
Count
属性,在集合中旋转并记录计数,向数据库或其他对象发送
Count(*)
查询

ORMs提供了一种让内存中的对象和数据库行相互反映的方法,其中一个对象的更改通过另一个对象的更改来反映

这很好地符合上面的“某种转换方法”。因此,Linq2SQL、EF和Linq2NHibernate都履行ORM角色和Linq提供者角色

考虑到Linq可以在集合上工作,您必须非常反常地创建一个根本不支持Linq的ORM(您必须将集合设计为不实现
IEnumerable
,因此不能使用
foreach
)。更直接的支持意味着你可以提供更好的支持。至少它应该有助于提高查询效率。例如,如果ORM为我们提供了一种获取反映
Users
表中所有行的
Users
对象的方法,那么我们将始终能够:

  int uID = (from u in Users where u.Username == "Alice" select u.ID).FirstOrDefault();
如果不通过使用
用户
实现
IQueryable
来直接支持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;
其次是:

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的全部目的是使操作数据库尽可能接近正在使用的编程语言中与DB无关的操作。在.NET中,这意味着Linq支持