我正在使用EF 5和.NET 4.5,我已经为我的数据库创建了一个模型并将我的函数导入到模型中,我可以成功导入TVF和SP但是我无法导入带有标量返回的函数值。
是否可以与设计师或我手动编辑edmx
文件?
答案 0 :(得分:8)
向下滚动到此页面上标量值函数部分:
Database First Development with Entity Framework 5 - Importing Scalar Valued Functions
你可以遵循这个丑陋的解决方法,或者你可以按照我在这个答案的最底部给出的建议。
以下是该文章的摘录(关于解决方法):
“此方法需要对.edmx文件的xml进行一些细微更改, 直。为此,右键单击.edmx文件并选择“打开” 使用......','XML(文本)编辑器'。这是函数的外观 更改前的.edmx文件:
<Function Name="CountActivities" ReturnType="int" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="false" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo">
<Parameter Name="personId" Type="int" Mode="In" />
</Function>
<Function Name="CountHydrations" ReturnType="int" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="true" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo">
<Parameter Name="personId" Type="int" Mode="In" />
</Function>
<Function Name="CountMeals" ReturnType="int" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="true" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo">
<Parameter Name="personId" Type="int" Mode="In" />
</Function>
“从元素中删除'ReturnType'属性。然后, 为每个元素添加一个元素。 请参阅下面修改后的.edmx文件以获取元素的内容。
<Function Name="CountActivities" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="false" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo">
<CommandText>
SELECT [dbo].[CountActivities] (@personId)
</CommandText>
<Parameter Name="personId" Type="int" Mode="In" />
</Function>
<Function Name="CountHydrations" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="true" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo">
<CommandText>
SELECT [dbo].[CountHydrations] (@personId)
</CommandText>
<Parameter Name="personId" Type="int" Mode="In" />
</Function>
<Function Name="CountMeals" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="true" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo">
<CommandText>
SELECT [dbo].[CountMeals] (@personId)
</CommandText>
<Parameter Name="personId" Type="int" Mode="In" />
</Function>
“接下来,在模型浏览器中,右键单击'功能导入' 文件夹并选择“添加功能导入...”这将显示“添加” 功能导入'对话框窗口。我们将导入'CountActivities' 标量值函数显示此方法。输入以下内容 对话框窗口中的信息,然后选择保存。“
我的建议: 考虑到所需的努力,更容易只创建一个表值函数,只返回一行以达到相同的效果和目的。
以下是SQL Server中用户定义的表值函数的示例:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[udfGetTotalMinutesInvoiced] ( @billingType INT )
RETURNS TABLE
AS
RETURN
(
SELECT
SUM([ProgressNote].[TotalMinutes]) AS 'TotalMinutesInvoiced'
FROM
[dbo].[InvoiceEntry]
JOIN [dbo].[ProgressNote]
ON [ProgressNote].[ProgressNoteID] = [InvoiceEntry].[ProgressNoteID]
WHERE
[InvoiceEntry].[BillingTypeID] = @billingType
AND progressNote.[IsRecordedInInvoiceEntry] = 1
)
GO
另请注意,您实际上可以在表值函数中调用标量值的用户定义函数。
要调用表值函数,您可能希望使用这样的FirstOrDefault方法:
private void UpdateStatisticsPanel()
{
var billingTypeId = int.Parse(txtBillingTypeId.Text);
var totalMinutesInvoiced = context.udfGetTotalMinutesInvoiced(billingType: billingTypeId);
var minutesInvoiced = totalMinutesInvoiced.FirstOrDefault();
var invoiced = new Tuple<string, int?>("totalMinutesInvoiced:", minutesInvoiced);
lstFinancialSummary.Items.Add(invoiced);
var totalMinutesNotInvoiced = context.udfGetTotalMinutesNotInvoiced(billingType: billingTypeId);
var minutesNotInvoiced = totalMinutesNotInvoiced.FirstOrDefault();
var notInvoiced = new Tuple<string, int?>("totalMinutesNotInvoiced:", minutesNotInvoiced);
lstFinancialSummary.Items.Add(notInvoiced);
// remember to push the values up to the ListView.
}
答案 1 :(得分:5)
在将近一天的时间里遇到同样的问题并且对@devinbost给予了应有的尊重,它并没有解决问题,但它使我更接近解决方案。总之,唯一的解决方案是将函数标量类型转换为表值类型,表中有一个值,请参阅代码示例。
您不必更改EDMX XML中的任何内容,请修改SQL函数
标量函数原样,它不起作用
CREATE FUNCTION [dbo].[GetSha256]
(
-- Add the parameters for the function here
@str nvarchar(max)
)
RETURNS VARBINARY(32)
AS
BEGIN
RETURN ( SELECT * FROM HASHBYTES('SHA2_256', @str) AS HASH256 );
END -- this doesn't work.
标量函数 - &gt;转换为表值函数,它可以工作
CREATE FUNCTION [dbo].[GetSha2561]
(
-- Add the parameters for the function here
@str nvarchar(max)
)
RETURNS @returnList TABLE (CODE varbinary(32))
AS
BEGIN
INSERT INTO @returnList
SELECT HASHBYTES('SHA2_256', @str);
RETURN; -- This one works like a charm.
END
Edmx截图
答案 2 :(得分:0)
我无法从存储过程中获取返回参数, 所以我在调用存储时使用了context.Database.ExecuteSqlCommand而不是“ SqlQuery”,它可以工作。希望这个建议可以对某人有所帮助。