呼叫使用实体框架从C#标量函数4.0 /的.edmx(Calling scalar function

2019-07-18 07:28发布

我想我的标量函数映射到我的.edmx但它失败。 我右键点击我的实体框架的映射,然后从数据库更新模型。 它出现在我的存储过程在我的模型浏览器文件夹中。

然而,当我想将它添加到我的Function Imports文件夹中的模型浏览器,邮件标量函数不会在下拉列表显示。 有人能帮我吗?

我可以用老办法,比如调用标量函数:

dbContext.ExecuteStoreQuery<DateTime?>(
"SELECT dbo.getMinActualLoadDate ({0}, {1}, {2}) AS MyResult", 
LoadPkid, LoadFkStartLoc, TripSheetPkid).First();

但它是不是最好的办法。 我的经理想我找到一种方法能够把在“功能导入”文件夹中的标量函数,所以我可以使用下面的代码调用标量函数,而不是以前的代码:

dbContext.ExecuteFunction("getMinActualLoadDate ", paramList);

我试图添加图像来显示我的意思,但因为我的名声仍然很低,我不能这样做。 然而,图像可以在这里找到: http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/756865e5-ff25-4f5f-aad8-fed9d741c05d

谢谢。

Answer 1:

我遇到同样的问题。 这里是解决方案,我已经找到了足够的适合我自己(在EF5测试,但也应该在EF4工作):

有没有支持的映射标量值功能开箱即用,但你可以直接执行它们。

您还可以编辑EDMX文件,以使EDMX产生标量值函数正确的方法,但是如果你会同步您的数据库模型,可以会被删除。

写标量值函数自己实现:

string sqlQuery = "SELECT [dbo].[CountMeals] ({0})";
Object[] parameters = { 1 };
int activityCount = db.Database.SqlQuery<int>(sqlQuery, parameters).FirstOrDefault();

或编辑EDMX并添加XML对于标量值函数的自定义马平:

<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>

这个信息在这个被发现的博客文章



Answer 2:

下面是我解决这个问题,这是几乎完全你的经理问什么..虽然18个月晚。

作为香草方法:

    /// <summary>
    /// Calls a given Sql function and returns a singular value
    /// </summary>
    /// <param name="db">Current DbContext instance</param>
    /// <typeparam name="T">CLR Type</typeparam>
    /// <param name="sql">Sql function</param>
    /// <param name="parameters">Sql function parameters</param>
    /// <param name="schema">Owning schema</param>
    /// <returns>Value of T</returns>
    public T SqlScalarResult<T>(DbContext db, 
                                string sql, 
                                SqlParameter[] parameters,
                                string schema = "dbo") {

        if (string.IsNullOrEmpty(sql)) {
            throw new ArgumentException("function");
        }

        if (parameters == null || parameters.Length == 0) {
            throw new ArgumentException("parameters");
        }

        if (string.IsNullOrEmpty(schema)) {
            throw new ArgumentException("schema");
        }

        string cmdText =
            $@"SELECT {schema}.{sql}({string.Join(",",
                parameters.Select(p => "@" + p.ParameterName).ToList())});";

        // ReSharper disable once CoVariantArrayConversion
        return db.Database.SqlQuery<T>(cmdText, parameters).FirstOrDefault();

    }

}

而作为一个扩展方法EF:

namespace System.Data.Entity {

    public static class DatabaseExtensions {

        /// <summary>
        /// Calls a given Sql function and returns a singular value
        /// </summary>
        /// <param name="db">Current DbContext instance</param>
        /// <typeparam name="T">CLR Type</typeparam>
        /// <param name="sql">Sql function</param>
        /// <param name="parameters">Sql function parameters</param>
        /// <param name="schema">Owning schema</param>
        /// <returns>Value of T</returns>
        public static T SqlScalarResult<T>(this Database db, 
                                           string sql, 
                                           SqlParameter[] parameters,
                                           string schema = "dbo") {

            if (string.IsNullOrEmpty(sql)) {
                throw new ArgumentException("sql");
            }

            if (parameters == null || parameters.Length == 0) {
                throw new ArgumentException("parameters");
            }

            if (string.IsNullOrEmpty(schema)) {
                throw new ArgumentException("schema");
            }

            string cmdText =
                $@"SELECT {schema}.{sql}({string.Join(",", 
                    parameters.Select(p => "@" + p.ParameterName).ToList())});";

            // ReSharper disable once CoVariantArrayConversion
            return db.SqlQuery<T>(cmdText, parameters).FirstOrDefault();

        }

    }

}

虽然它并没有在这里抽烟,我会建议之前任何严重的使用单元测试。



Answer 3:

我猜你错过了Edit Function Import对话框,在这里你可以生成复杂类型 。 尝试探索。

如果您已成功创建了scalars ,你现在可以浏览这样的

using (var con = new DatabaseEntities())
{
   long? invoiceNo = con.sp_GetInvoiceMaxNumber(code.Length + 2).First();
   ....
}


Answer 4:

所述一个和唯一的解决办法是把标量函数类型表值类型转换与所述表中的单个值,请参见代码示例。

您不必在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.

标量函数 - >转换为表值函数,它的工作原理

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



文章来源: Calling scalar function from c# using Entity Framework 4.0 / .edmx