如何让EntityFramework6在CSDL中使用SQLSTUFF函数

本文关键字:SQLSTUFF 函数 CSDL EntityFramework6 | 更新日期: 2023-09-27 18:29:08

我使用的是EF 6.1,希望在EDMX文件的CSDL部分创建一个自定义函数,该函数可以调用SQL 2012中内置的STUFF函数。
我所拥有的很简单。(注意:假设时间为HHMM,不带冒号)

<Function Name="StringToDate" ReturnType="DateTime">
    <Parameter Name="strDate" Type="String" />
    <Parameter Name="strTime" Type="String" />
    <DefiningExpression>
        CAST(CASE WHEN strDate &lt;&gt; '' THEN strDate + ' ' 
            + STUFF(strTime, 3, 0, ':') END AS DateTime)
    </DefiningExpression>
</Function>

如果我删除了"STUFF"命令,但使用了"STUFF"命令,我会得到"‘STUFF’无法解析为有效的类型或函数",则上述代码有效

我可以在LINQ to Entity中使用"Entity.SqlServer.SqlFunctions.Stuff",但在CSDL中不行。

注意:我使用STUFF命令在时间变量的第2个和第3个字符之间插入一个冒号。

编辑:"解决问题"
以下是解决方法,但如果可能的话,我仍然想知道如何在CSDL中使用STUFF。

CAST(CASE WHEN strDate &lt;&gt; '' THEN strDate + ' ' +  SUBSTRING(strTime, 1, 2) + ':' + SUBSTRING(strTime, 3, 2) END AS DateTime)



编辑:目前,我已将此作为一个问题发布在codeplex上。如果你感兴趣,请投票
https://entityframework.codeplex.com/workitem/2583

如何让EntityFramework6在CSDL中使用SQLSTUFF函数

在数据库提供程序中声明的函数通常在提供程序的命名空间下可用。因此,如果这是一个普通的实体SQL查询,您应该能够调用STUFF(),在它之前添加SqlServer,例如SqlServer.SUFF(strTime,3,0,':')。

然而,模型定义函数主体中的实体SQL只能引用其他规范函数或其他模型定义函数,即模型定义函数不能通过引用特定于提供者的函数而变得特定于提供者。

这是一个选择采用的限制。当应用程序执行LINQ查询时,您可以执行特定于提供程序的函数,因为您的应用程序已经依赖于具有概念和存储模式以及映射规范的完整模型。另一方面,模型定义的函数是概念模型的一部分,概念模型应该是自包含的:您应该能够将提供程序、存储模式或映射规范交换为不同的规范,而不会使概念模型无效。因此,概念模型中定义的事物不能依赖于其他地方定义的事物。

解决方法:

我做了一些实验,想出了一种简单的方法来模拟SQL Server的Stuff(),只使用应该跨提供者工作的规范函数。通过指定概念模型的命名空间,例如Model1.Stuff(strTime,3,0,':'),您可以从自己的模型定义函数中使用类似的东西

<Function Name="Stuff" ReturnType="String">
  <Parameter Name="character_expression" Type="String" />
  <Parameter Name="start" Type="Int32" />
  <Parameter Name="length" Type="Int32" />
  <Parameter Name="replaceWith_expression" Type="String" />
  <DefiningExpression>
    Left(character_expression,start-1) 
    + replaceWith_expression 
    + Substring(character_expression, start + length, Length(character_expression))
  </DefiningExpression>
</Function>