mik*_*igs 4 projection linq-to-sql
我在使用Func在LINQ to SQL查询中使用投影时发现了一些意外行为.示例代码将比单词更好地解释.
使用投影的基本L2S lambda查询:
db.Entities.Select(e => new DTO(e.Value));
Run Code Online (Sandbox Code Playgroud)
它转换为所需的SQL:
SELECT [t1].[Value]
FROM [Entity] AS [t1]
Run Code Online (Sandbox Code Playgroud)
但是,当投影放入Func时,如下所示:
Func<Entity, DTO> ToDTO = (e) => new DTO(e.Value);
Run Code Online (Sandbox Code Playgroud)
并且这样称呼:
db.Entities.Select(e => ToDTO(e));
Run Code Online (Sandbox Code Playgroud)
SQL现在撤回表中的所有列,而不仅仅是投影中的列:
SELECT [t1].[Id], [t1].[Value], [t1].[timestamp], [t1].[etc...]
FROM [Entity] AS [t1]
Run Code Online (Sandbox Code Playgroud)
所以我的问题是,如何在没有LINQ to SQL实例化整个实体的情况下封装这个投影?
要记住的事情,我使用的DTO有一个受保护的默认构造函数,所以我不能使用对象初始化程序.由于无法修改DTO类,我必须创建一个子类来实现该行为.哪个好,如果这是唯一的解决方案.
谢谢.
编辑:
感谢Brian的解决方案.我之前尝试过一个Expression但无法弄清楚语法.这是工作代码:
Expression<Entity, DTO> ToDTO = (e) => new DTO(e.Value);
Run Code Online (Sandbox Code Playgroud)
然后像这样称呼它:
db.Entities.Select(ToDTO);
Run Code Online (Sandbox Code Playgroud)
起初我试图像这样调用它,这不会编译.这是调用Func的正确语法,但不是表达式.
db.Entities.Select(e => ToDTO(e));
Run Code Online (Sandbox Code Playgroud)
你可能需要创建一个Expression,而不是一个Func
Expression<Func<Entity, DTO>> ToDTO = (e) => new DTO(e.Value);
Run Code Online (Sandbox Code Playgroud)
IQueryable扩展方法适用于Expressions,而不是Funcs
通过传入a Func,你可能正在调用IEnumerable扩展方法,这就是为什么Linq2Sql的行为方式.
| 归档时间: |
|
| 查看次数: |
1571 次 |
| 最近记录: |