2014-11-03 52 views
4

我正在使用EF 6.1并希望在EDMX文件的CSDL部分创建一个可以调用内置于SQL 2012中的STUFF函数的自定义函数。
我拥有的非常简单。 (注意:这假定时间是HHMM没有冒号)如何让Entity Framework 6在CSDL中使用SQL STUFF函数?

<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”命令我得到“‘东西’不能被解析为有效类型或功能“。

我可以在LINQ to Entity中使用“Entity.SqlServer.SqlFunctions.Stuff”,但不能在CSDL中使用。

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

编辑:“工作”
这是工作,但我仍然想知道如何在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

+0

CSDL是一种不是存储模型(SSDL)的概念模型。 CSDL中的查询必须是有效的实体SQL,而SSDL中的查询必须是数据库的有效SQL。您必须在实体SQL中查找“Entity.SqlServer.SqlFunction.Stuff”的全名,或者(更好地)使用具有真实SQL的商店定义函数并将其映射为在CSDL中运行。 – 2014-11-17 14:27:32

+0

@LadislavMrnka谢谢你澄清CSDL/SSDL的差异。我可以创建一个可以调用“STUFF”函数的自定义函数,并将该函数放入SSDL中,但我希望能够使用CSDL中已有的自定义函数中的“STUFF”函数。我上面列出的例子是非常裸露的骨头,并没有显示我在CSDL中的完整功能。我在CSDL中编写的函数确实理解一些内置的SQL函数,我希望它理解“STUFF”函数。 – goroth 2014-11-17 16:12:43

回答

1

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

但是,模型定义函数的主体中的实体SQL只能引用其他规范函数或其他模型定义的函数,即模型定义的函数不能通过引用提供者特定函数使提供者特定。

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

解决方法:

我做了一些实验,并用这种简单的方式使用应在整个提供商合作,只有规范的功能,以模拟SQL Server的东西()走了过来。通过指定概念模型的命名空间,你可以从你自己的模型定义的函数中使用类似的东西,例如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> 
+0

它仍然不允许我在CSDL函数内调用STUFF命令。在LINQ中,我已经可以使用Entity.SqlServer.SqlFunctions.Stuff作为MS SQL STUFF命令。关于你的功能的好处是,它可以在各个提供商中使用。 – goroth 2014-12-12 02:52:27

+0

我在第三段填写了一些细节。虽然理论上可以取消限制,但存在限制的设计相关原因。 – divega 2014-12-16 18:14:52

相关问题