我们有一个超过 500 列的客户非常大的表(我知道有人会这样做!)
其中许多列实际上是其他表的外键。
我们还要求急切加载一些相关的表格。
在Linq to SQL或Dynamic Linq中是否有任何方法可以指定从数据库中检索哪些列? 我正在寻找一个linq语句,它实际上对生成的SQL语句产生了这种影响:
SELECT Id, Name FROM Book
当我们运行EF生成的reguar查询时,SQL Server会抛出一个错误,表明您已达到查询中可以选择的最大列数!!!
非常感谢任何帮助!
是的确是这种情况,该表有500列,并且自动引用我们的工具,自动加载第一级关系,这就达到了可以查询的列数的SQL限制。
我希望我可以设置为仅加载相关实体的有限列,例如Id和Name(在UI中用于向用户查看记录)
我想另一个选择是控制应该加载哪些FK列。但是,对于具有二进制或ntext列的表,这仍然存在问题,您可能不希望一直加载它。
有没有办法将多个模型(实体)挂钩到Code First中的同一个表?我们尝试这样做,我认为努力失败了。
答案 0 :(得分:18)
是的,您只能使用投影返回列的子集:
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到对象中的物化数据进行对映射实体的投影。
编辑:
可能存在一些误解EF如何工作的误解。 EF在实体之上工作 - 实体是您映射的。如果将500列映射到实体,则EF只会在您定义实体时使用该实体。这意味着查询加载实体并持久保存实体。
为什么这样工作?实体被视为原子数据结构,其数据只能加载和跟踪一次 - 这是将更改正确保存到数据库的能力的关键特性。这并不意味着您不应该只在需要时加载列的子集,但是您应该理解加载列的子集不会定义您的原始实体 - 它被视为实体中数据的任意视图。没有跟踪此视图,并且无需额外工作就无法将其保留回数据库(仅仅因为EF不包含有关投影原点的任何信息)。
EF还对映射实体的能力施加了一些额外的限制
Linq-to-Sql还包含将列标记为延迟加载的功能,但此功能目前在EF中不可用 - 您可以vote for that feature。
它会带来您的优化选项
答案 1 :(得分:0)
创建查询所需列数的存储过程,然后从代码中调用存储过程。