LINQ to SQL 投影:Func 与 Inline

发布于 2024-10-11 13:53:14 字数 1118 浏览 3 评论 0原文

在使用 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 类无法修改,因此我必须创建一个子类来实现该行为。如果这是唯一的解决方案,那很好。

谢谢。

编辑:

感谢布莱恩提供的解决方案。我之前尝试过表达式,但无法弄清楚语法。这是工作代码:

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

然后像这样调用它:

db.Entities.Select(ToDTO);

起初我试图这样调用它,但无法编译。这是调用 Func 的正确语法,但不是调用 Expression 的正确语法。

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

I am finding some unexpected behavior when using a projection in a LINQ to SQL query using a Func. Example code will explain better than words.

A basic L2S lambda query using projection:

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

It translates to the desired SQL:

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

However, when the projection is put into a Func like this:

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

And called like this:

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

The SQL is now pulling back all of the columns in the table, not just the one in the projection:

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

So my question is, how do I encapsulate this projection without the LINQ to SQL instantiating the whole Entity?

Things to keep in mind, the DTO I am using has a protected default constructor, so I can't use an object initializer. And since the DTO class cannot be modified, I'd have to make a subclass to implement that behavior. Which is fine, if that's the only solution.

Thanks.

Edit:

Thanks to Brian for the solution. I had previously tried an Expression but couldn't figure out the syntax. Here's the working code:

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

Then call it like this:

db.Entities.Select(ToDTO);

At first I was trying to call it like this, which wouldn't compile. This is the proper syntax for calling a Func, but not an Expression.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

甜是你 2024-10-18 13:53:14

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

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

IQueryable 扩展方法适用于 Expression,而不是 Func

通过传入 Func,您可能会调用 IEnumerable 扩展方法,这就是 Linq2Sql 如此运行的原因。

You probably need to create an Expression, not a Func

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

IQueryable extension methods work with Expressions, not Funcs

By passing in a Func, you are probably invoking the IEnumerable extension method, which is why Linq2Sql is acting the way it is.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文