在Linq查询中调用方法

use*_*635 32 c# linq linq-to-sql

我想在我的表中插入一个名为'S'的列,它将根据从表列获取的值获得一些字符串值.

例如:for each ID (a.z)我想将它的字符串值存储在另一个表中.字符串值从另一个通过Linq查询获取它的方法返回.

  • 是否可以从Linq调用方法?
  • 我应该在同一个查询中做所有事情吗?

这是我需要获得的信息的结构:

az是表#1中第一个方块中的ID,从这个ID我得到表#2中的另一个id,从中我可以得到我需要在列'S'下显示的字符串值.
在此输入图像描述

var q = (from a in v.A join b in v.B
    on a.i equals b.j
    where a.k == "aaa" && a.h == 0
    select new {T = a.i, S = someMethod(a.z).ToString()})
    return q;
Run Code Online (Sandbox Code Playgroud)

S = someMethod(a.z).ToString()导致以下错误的行:

无法将类型为"System.Data.Linq.SqlClient.SqlColumn"的对象强制转换为"System.Data.Linq.SqlClient.SqlMethodCall".

Bro*_*ass 55

你必须在Linq-to-Objects上下文中执行你的方法调用,因为在数据库方面,方法调用没有意义 - 你可以使用AsEnumerable()- 基本上其余的查询将被评估为内存集合使用Linq-to-Objects,你可以使用方法按预期调用:

var q = (from a in v.A join b in v.B
        on a.i equals b.j
        where a.k == "aaa" && a.h == 0
        select new {T = a.i, Z = a.z })
        .AsEnumerable()
        .Select(x => new { T = x.T, S = someMethod(x.Z).ToString() })
Run Code Online (Sandbox Code Playgroud)

  • 我只是想确定一下,所以它迭代了 Enumerable 两次,不是吗?首先,在 `.AsEnumerable()` 之前,其次,在 `.AsEnumerable()` 之后? (2认同)
  • 这不是一个好主意@fthopkins - 这会导致整个表加载到内存中,而不是在数据库上运行“where”子句。 (2认同)

Ken*_*ith 11

您需要将其拆分为两个语句.返回查询中的结果(这将是命中数据库的结果),然后在单独的步骤中第二次枚举结果,以将转换转换为新的对象列表.第二个"查询"不会访问数据库,因此您将能够在其中使用someMethod()它.

Linq-to-Entities有点奇怪,因为它使从C#查询数据库的过渡非常无缝:但你总是要提醒自己,"这个C#将被翻译成一些SQL." 结果,你必须问自己,"所有这些C#实际上都可以作为SQL执行吗?" 如果它不能 - 如果你在someMethod()里面调用- 你的查询将遇到问题.通常的解决方案是拆分它.

(@BrokenGlass使用的另一个答案.AsEnumerable()基本上是另一种方法.)