如何在EF 5中导入具有标量返回值的函数

时间:2013-08-11 07:56:43

标签: c# entity-framework

我正在使用EF 5和.NET 4.5,我已经为我的数据库创建了一个模型并将我的函数导入到模型中,我可以成功导入TVF和SP但是我无法导入带有标量返回的函数值。 是否可以与设计师或我手动编辑edmx文件?

3 个答案:

答案 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截图

enter image description here

答案 2 :(得分:0)

我无法从存储过程中获取返回参数, 所以我在调用存储时使用了context.Database.ExecuteSqlCommand而不是“ SqlQuery”,它可以工作。希望这个建议可以对某人有所帮助。