gpt4 book ai didi

entity-framework - 使用 EF Code First 从数据库中选择特定列

转载 作者:行者123 更新时间:2023-12-03 11:55:18 24 4
gpt4 key购买 nike

我们有一个客户非常大的 table 超过 500 专栏(我知道有人这样做!)

许多这些列实际上是其他表的外键 .

我们也有需求急切负载 一些相关的表。

在 Linq to SQL 或 Dynamic Linq 中是否有任何方法可以指定要从数据库中检索哪些列?
我正在寻找一个实际上对生成的 SQL 语句有这种影响的 linq 语句:

SELECT Id, Name FROM Book

当我们运行 EF 生成的 reguar 查询时,SQL Server 抛出一个错误,您已达到查询中可以选择的最大列数!!!

非常感谢任何帮助!

是的,正是这种情况,该表有 500 列,并且正在自引用我们的工具,自动预先加载第一级关系,这达到了可查询列数的 SQL 限制。

我希望我可以设置为仅加载相关实体的有限列,例如 Id 和 Name(在 UI 中用于向用户查看记录)

我想另一种选择是控制应该急切加载哪些 FK 列。但是,对于具有您可能不想一直加载的 binary 或 ntext 列的表,这仍然存在问题。

有没有办法在 Code First 中将多个模型(实体)连接到同一个表?我们尝试这样做,我认为这种努力失败了。

最佳答案

是的,您可以使用投影仅返回列的子集:

var result = from x in context.LargeTable
select new { x.Id, x.Name };

问题:投影和预先加载不能一起工作。一旦开始使用投影或自定义连接,您就会改变查询的形状,并且不能使用 Include (EF 会忽略它)。在这种情况下,唯一的方法是在投影结果集中手动包含关系:
var result = from x in context.LargeTable
select new {
Id = x.Id,
Name = x.Name,
// You can filter or project relations as well
RelatedEnitites = x.SomeRelation.Where(...)
};

您还可以投影到特定类型,但不能映射特定类型(例如,您不能投影到我的示例中的 LargeTable 实体)。映射到映射实体只能在 Linq-to-objects 中的物化数据上完成。

编辑:

可能存在一些误解 EF 的工作原理。 EF 在实体之上工作 - 实体是您映射的内容。如果您将 500 列映射到实体,EF 只需按照您定义的方式使用该实体。这意味着查询加载实体并持久保存实体。

为什么它以这种方式工作?实体被认为是原子数据结构,它的数据只能加载和跟踪一次——这是将更改正确地保存回数据库的关键特性。这并不意味着您不应该在需要时仅加载列子集,但您应该了解加载列子集并没有定义您的原始实体 - 它被视为实体中数据的任意 View 。此 View 不会被跟踪,也无法在没有额外工作的情况下持久保存回数据库(仅仅是因为 EF 不保存有关投影来源的任何信息)。

EF 还对映射实体的能力施加了一些额外的限制
  • 每个表只能正常映射一次。为什么?再次因为将表多次映射到不同的实体可能会破坏正确持久化这些实体的能力 - 例如,如果任何非键列被映射两次并且您加载映射到同一记录的两个实体的实例,您将在此期间使用哪个映射值保存更改?
  • 有两个异常(exception)允许您多次映射表
  • 每个层次结构继承的表 - 这是一个映射,其中表可以包含来自继承层次结构中定义的多个实体类型的记录。映射到层次结构中的基本实体的列必须由所有实体共享。每个派生实体类型都可以将其自己的列映射到其特定属性(其他实体类型的这些列始终为空)。无法在多个实体之间共享派生属性的列。还必须有一个名为 discriminator 的附加列,告诉 EF 记录中存储了哪种实体类型 - 此列不能映射为属性,因为它已映射为类型鉴别器。
  • 表拆分 - 这是单表映射限制的直接解决方案。它允许您将表拆分为具有一些约束的多个实体:
  • 实体之间必须存在一对一的关系。您有一个用于加载核心数据的中央实体,所有其他实体都可以通过该实体的导航属性访问。急切加载、延迟加载和显式加载正常工作。
  • 关系是 1-1 实数,因此部分或关系必须始终存在。
  • 实体不能共享除键之外的任何属性 - 此约束将解决最初的问题,因为每个可修改的属性仅映射一次
  • 拆分表中的每个实体都必须具有映射的键属性
  • 插入需要填充整个对象图,因为其他实体可以包含映射的所需列

  • Linq-to-Sql 还包含将列标记为延迟加载的功能,但此功能目前在 EF 中不可用 - 您可以 vote for that feature .

    它会导致您的优化选项
  • 使用投影获取实体的只读“ View ”
  • 你可以在 Linq 查询中做到这一点,正如我在本答案的前一部分
  • 中所展示的那样
  • 您可以创建数据库 View 并将其映射为新的“实体”
  • 在 EDMX 中,您还可以使用定义查询或查询 View 来封装映射中的 SQL 或 ESQL 投影
  • 使用表拆分
  • EDMX 允许您毫无问题地将表拆分为多个实体
  • Code first allows you splitting table同样,但是当您将表拆分为两个以上的实体时会出现一些问题(我认为它要求每个实体类型都具有从拆分表到所有其他实体类型的导航属性 - 这使得它真的很难使用)。
  • 关于entity-framework - 使用 EF Code First 从数据库中选择特定列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11528988/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com