LINQ to SQL Projection:Func vs Inline

时间:2011-01-13 17:59:28

标签: linq-to-sql projection

在使用Func在LINQ to SQL查询中使用投影时,我发现了一些意外行为。示例代码将比单词更好地解释。

使用投影的基本L2S lambda查询:

db.Entities.Select(e => new DTO(e.Value));

它转换为所需的SQL:

SELECT [t1].[Value]
FROM [Entity] AS [t1]

然而,当投影放入这样的Func中时:

Func<Entity, DTO> ToDTO = (e) => new DTO(e.Value);

并且这样称呼:

db.Entities.Select(e => ToDTO(e));

SQL现在撤回表中的所有列,而不仅仅是投影中的列:

SELECT [t1].[Id], [t1].[Value], [t1].[timestamp], [t1].[etc...]
FROM [Entity] AS [t1]

所以我的问题是,如何在没有LINQ to SQL实例化整个实体的情况下封装这个投影?

要记住的事情,我使用的DTO有一个受保护的默认构造函数,所以我不能使用对象初始化程序。由于无法修改DTO类,我必须创建一个子类来实现该行为。如果这是唯一的解决方案,那很好。

感谢。

编辑:

感谢Brian的解决方案。我之前尝试过一个Expression但无法弄清楚语法。这是工作代码:

Expression<Entity, DTO> ToDTO = (e) => new DTO(e.Value);

然后这样称呼:

db.Entities.Select(ToDTO);

起初我试图像这样调用它,这不会编译。这是调用Func的正确语法,但不是表达式。

db.Entities.Select(e => ToDTO(e));

1 个答案:

答案 0 :(得分:5)

您可能需要创建Expression,而不是Func

Expression<Func<Entity, DTO>> ToDTO = (e) => new DTO(e.Value);

IQueryable扩展方法适用于Expression s,而非Func s

通过传递Func,您可能正在调用IEnumerable扩展方法,这就是为什么Linq2Sql的行为方式。