【问题标题】:Linq - how does it work?Linq - 它是如何工作的?
【发布时间】:2010-03-19 20:25:04
【问题描述】:

我刚刚用 ASP.Net 研究了 Linq。确实非常整洁。我只是想知道-如何填充所有类?我的意思是在 ASP.Net 中,假设您有一个名为 Catalogue 的 Linq 文件,然后您使用 For 循环遍历 Catalogue.Products 并打印每个产品名称。详细信息如何存储?它是否只是在页面加载时遍历 Products 表并为每一行创建另一个 Product 类实例,从而有效地将整个表复制到 Product 类数组中?

如果是这样,我想我已经创建了一个非常像这样的系统,因为有一个带有每个 Manager 类实例的 SiteContent 模块 - 例如有 UserManager、ProductManager、SettingManager 等。 UserManager 为 Users 表中的每一行包含一个 User 类的实例。它们还包含创建、更新和删除等方法。这些经理和他们的“项目”是在每次页面加载时创建的。就我作为开发人员而言,这只是让访问每个页面中的用户、产品、设置等变得既好又容易。我需要创建的任何后续页面,我只需要引用 SiteContent.UserManager 来访问用户列表,而不是从该页面内执行查询(即,此方法将数据访问与页面的工作分开,在与使用后面的代码相同的方式将页面的工作方式与页面的布局方式分开)。

但问题是这种技术似乎相当缓慢。我的意思是它在每次页面加载时有效地创建一个数据库,从另一个数据库获取数据。我已经采取了一些措施,例如防止在页面加载时未引用 ProductManager 时创建它。因此它不会在不需要时将数据加载到存储中。

我的问题基本上是我的技术是否与 Linq 做完全相同的事情,在将数据从表复制到类的属性的意义上..

提前感谢您对此的任何建议或答案。

问候,

理查德·克拉克

标签: .net asp.net linq linq-to-sql


【解决方案1】:

Linq to SQL 不会维护数据库中所有数据的副本。它通过IQueryable 接口获取您提供给它的表达式,读取表达式树,并使用WHERE 和其他SQL 构造将它们转换为实际的SQL 语句。

换句话说,当你写这个时:

var product = context.Products.Where(p => p.ID == 50).SingleOrDefault();

它对数据库执行此操作:

SELECT ID, Name, Foo, Bar, Baz, Blah, ...
FROM Products
WHERE ProductID = 50

只是做一个SELECT * FROM Products,然后从结果中搜索特定的产品。

如果您尝试在每次页面加载时“下载”整个数据库,您的应用程序确实会很慢。这绝对不是 Linq to SQL、Linq to Entities 或任何其他 ORM 框架所做的。

【讨论】:

  • 补充一句:这是我近 20 年前使用的技术。 10 年前在 C# 上。没什么新鲜的,关于它的文献很多。
  • 感谢您的回复。我想也许这个答案以我可以很容易理解的方式向我解释(并不是说我无法理解其他答案..)。我只对 Linq 进行了一些研究,因为我的整个项目(和论文)将在不到 2 个月的时间内完成,而且我还没有做太多论文:(。这是我可以很容易评论的事情,因为我会改变如果我有时间。感谢所有人的回答 - 非常感谢。问候,理查德
【解决方案2】:

Linq-to-SQL 绝对不会“在每次加载页面时都创建一个数据库”.....您需要了解 Linq-to-SQL 的工作原理以及它的作用。

我的建议:查看“The Gu” - Scott Guthrie 的 multi-part series of blog post,并在这些帖子中吸收所有这些智慧。

视觉设计师背后隐藏着很多魔力,它基本上创建了表格结构的“快照” - 但只是结构!它还知道如何将您的“给我那些记录”查询转换为针对 SQL Server 后端的直接 T-SQL 查询。并且它将这些相关的点点滴滴转换成漂亮的 .NET 对象。

足够先进的技术总是与魔法几乎没有区别 - 但 Linq 和 Linq-to-SQL 真的不是黑魔法 - 只是一些聪明人的非常聪明的代码!

【讨论】:

  • 在 Reflector 中打开 ObjectReaderCompiler 并尝试告诉我所有这些 Emit 调用都不是黑魔法。 ;)
  • @Aaronaught:好的,大部分的 LINQ 和 Linq-to-SQL 真的不是什么黑魔法 - 有些部分可能是 :-)
【解决方案3】:

魔法 ;-)

不,但它非常神奇。 LINQ 的工作原理相当复杂,但我发现使用 LINQ 几乎总能获得更好或同等的性能,而且代码总是更简洁。

如果您想使用 LINQ,请下载 LINQPad 并查看示例。然后购买 Joe Albahari(作者)的书,C# 4.0 In a Nutshell,了解所有血腥细节!

【讨论】:

    【解决方案4】:

    您将需要花一点时间熟悉 LINQ 语法并了解如何仅提取您需要的数据。我建议下载LINQPad...详细示例,并为您提供一个不错的沙盒游戏,让您的脚湿透。一旦你掌握了基础知识,就会有时间更多地参与......

    【讨论】:

      【解决方案5】:

      LINQ To SQL 提供程序与 C# 编译器共谋,与内存集合中的标准 (IEnumerable) 相比,IQueryable 接口在编译时的行为略有不同。构建了表达式树,this post 非常有助于理解幕后发生的事情。 LINQ to SQL 提供程序接受表达式,而不是函数和操作。详情见帖子。

      【讨论】:

      • 勾结?除非您包含所有 .net 编译语言以及每个 linq 提供程序(例如 LinqToEntities),否则不会。那么它更像是一个聚会而不是勾结。
      【解决方案6】:

      在 Linq 中,您创建一个数据上下文来管理数据库和对象模型之间的数据更改。

      有一些工具,例如设计器,或 sqlmetal,允许您在数据库表字段和对象模型之间创建映射。

      对于断开连接的模型,例如 asp.net,您可以使用附加方法来维护字段更新等。

      我目前正在阅读一本非常好的关于 Linq 的书,名为 Linq in Action,它很好地介绍了 Linq。至于将您的模型与 Linq 所做的比较,您可能需要做一些阅读,因为 Linq 在代码级别管理对象和将此代码转换到数据层之间执行了大量管理。

      使用 Linq to SQL 有一个表达式层,它使用非常密集的数据提供程序将目标代码转换为 sql。

      Linq 使用一种叫做表达式树的东西向您公开这个表达式层。然后,您可以修改表达式树中的这些节点,以修改随后在数据层生成的代码。

      【讨论】:

        【解决方案7】:

        LINQ to SQL 就像许多Object Relationship Mapping 解决方案一样,创建对象和集合,将表抽象为面向对象的实体。您为不同实体创建管理器类的方法有点夸大其词,并且很容易变得笨拙。您可能想考虑使用存储库模式和Domain Driven Design,这实际上意味着您将关联到几个高级类中的实体组合在一起。

        【讨论】:

          【解决方案8】:

          Linq 是 monad 的集合。单子如何工作由范畴论描述。因此,如果您真的非常想知道,请查找 monad。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-12-23
            • 2010-09-24
            • 2021-09-26
            • 2011-03-18
            • 2015-06-16
            • 2012-08-31
            • 2012-07-13
            相关资源
            最近更新 更多