从 Linq Query 调用 SQL 标量函数
Posted
技术标签:
【中文标题】从 Linq Query 调用 SQL 标量函数【英文标题】:Calling SQL scalar function from Linq Query 【发布时间】:2016-03-12 21:39:05 【问题描述】:这里有很多类似的线程,但是没有一个解决不了我的问题。
据我所知,从 linq 调用 SQL 标量函数有两种方法。
1。方法:
我已使用 XML 编辑器将我的函数添加到 .edmx 文件中,我的函数是:
<Function Name="prisustvoPostotci" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="false" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo">
<CommandText>
select dbo.prisustvoPostotci(@matica_ID,@godina)
</CommandText>
<Parameter Name="matica_ID" Type="int" Mode="In" />
<Parameter Name="godina" Type="int" Mode="In" />
</Function>
我进入模型浏览器并在Function Imports中双击我的函数并将返回集合类型更改为Int32。我的函数返回整数。
现在我可以使用以下方法从 linq 调用我的函数:
using (DB_Entities dm = new DB_Entities())
dm.prisustvoPostotci(1, 2016).FirstOrDefault();
它返回有效的整数值!
但是如果我像这样从 Linq Query 调用我的函数:
query = query.Where(x => x.date.Value.Year == max_year &&
dm.prisustvoPostotci(x.ID, max_year).FirstOrDefault() >= 50);
它会抛出这个错误:
LINQ to Entities 无法识别该方法 'System.Data.Entity.Core.Objects.ObjectResult
1[System.Nullable
1[System.Int32]] prisustvoPostotci(System.Nullable1[System.Int32], System.Nullable
1[System.Int32])' 方法,而这个方法不能 翻译成商店表达式。
2。方法:
我已使用 XML 编辑器将我的函数添加到 .edmx 文件中,我的函数是:
<Function Name="prisustvoPostotci" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="false" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo">
<CommandText>
select dbo.prisustvoPostotci(@matica_ID,@godina)
</CommandText>
<Parameter Name="matica_ID" Type="int" Mode="In" />
<Parameter Name="godina" Type="int" Mode="In" />
</Function>
我进入模型浏览器并在Function Imports中双击我的函数并将返回集合类型更改为Int32。我的函数返回整数。
然后我创建了一个分部类并写了这个方法:
public static class EntityFunctions
[EdmFunction("Model.Store", "prisustvoPostotci")]
public static int prisustvoPostotci(int matica_ID, int godina)
throw new NotSupportedException("Direct calls not supported");
“Model.Store”是从 .edmx 文件中的架构命名空间中读取的模型存储的正确名称。
现在,如果我使用 linq 从 linq 调用我的函数:
EntityFunctions.prisustvoPostotci(119, 2016).ToString()
它会抛出这个错误:
throw new NotSupportedException("不支持直接调用");
另外,如果我像这样从 Linq Query 调用我的函数:
query = query.Where(x => x.date.Value.Year == max_year &&
EntityFunctions.prisustvoPostotci(x.ID, max_year) >= 50);
它会抛出这个错误:
函数或函数 import 'Model.Store.prisustvoPostotci' 不可组合。不能在查询表达式中调用不可组合的函数或函数导入。
我试图编辑我的 .edmx 文件并更改属性 IsComposable="true",但它给了我这个错误:
声明命令文本的函数不能组合。
你能帮我解决这个问题吗!? 非常感谢提前!!
::欢呼声::
乔斯普
【问题讨论】:
你应该定义一个返回类型:programmaticponderings.wordpress.com/2012/11/22/… 如果您打算将 ReturnType="int" 或 ReturnType="Int32" 添加到我的 .edmx 文件中,则会返回此错误:“无法组合的函数不得声明返回类型。” ?? 您正在尝试将标量函数用作可组合函数(即可在查询中使用,例如在您的Where
子句中)。这只支持表值函数。
我对表函数不熟悉。是否可以实现表函数而不是标量函数以返回整数值?
【参考方案1】:
感谢 Gerd Arnold,我意识到标量函数不能在查询 where 语句中使用。
这是我通过在查询之外调用标量函数来过滤查询的方法:
var result = query.ToList();
for (int i = 0; i < result.Count; i++)
// prisustvoPostotci(ID, year) is my scalar function
if (dm.prisustvoPostotci(result[i].ID, max_year).FirstOrDefault() >= 50)
result.Remove(result[i]);
i--;
这样调用标量函数就可以了,我们可以从结果中删除匹配的记录!
希望这会对某人有所帮助。
:: 干杯 ::
乔斯普
【讨论】:
以上是关于从 Linq Query 调用 SQL 标量函数的主要内容,如果未能解决你的问题,请参考以下文章
在LINQ to Entities查询中调用自定义标量数据库函数?
使用 EXECUTE 从 SQL Server 调用用户定义函数时的标量结果不同