错误6046:无法生成存储函数的函数导入返回类型

问题描述 投票:0回答:3

我的 SQL 数据库中有一个标量值函数。

将此函数导入实体框架模型时收到此错误:

错误 6046:无法生成存储函数“GetContentByIdAndCul”的函数导入返回类型。
store 函数将被忽略,并且不会生成函数导入。 ..\EntityModels.edmx

我的T-SQL函数是:

ALTER FUNCTION [FRM].[GetContentByIdAndCul] 
    (@Id int,@Culture nvarchar(5))
RETURNS nvarchar(max)
AS
BEGIN
    declare @Result nvarchar(max)

    if @Id is not null
        set @Result='This Content not defined in this Language'
    
    select @Result=Value from CUL.Contents
    WHERE ID=@Id AND (CUL.Contents.Culture = LOWER(@Culture) 
          OR CUL.Contents.Culture = LOWER(SUBSTRING(@Culture,1,2))) 
    return @Result      
END
entity-framework linq user-defined-functions sql-function
3个回答
15
投票

前面的答案显示了解决问题的好方法,但在现实生活中没有一个有效。

这是一个经过测试的解决方案,其中

Entity Framework 6
对我有用。所以它应该适合你。

导入标量值函数

将标量值函数

[FRM].[GetContentByIdAndCul]
导入到实体框架模型中。它会自动在您的
EntityModels.edmx
文件的存储模型中创建相应的条目:

<Function Name="GetContentByIdAndCul" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="true" ParameterTypeSemantics="AllowImplicitConversion" Schema="FRM" ReturnType="nvarchar(max)">
      <Parameter Name="Id" Type="int" Mode="In" />
      <Parameter Name="Culture" Type="nvarchar(5)" Mode="In" />
</Function>

添加代码以包装对标量值函数的调用

创建新的源文件并使用部分类机制将代码添加到自动生成的

DbContext
类(假设她的名字是
MyEntities
)(https://msdn.microsoft.com/en-us/library/wa80x488%28v= vs.120%29.aspx)

public partial class MyEntities
{
    [DbFunction("EntityModels.Store", "GetContentByIdAndCul")]
    public string GetContentByIdAndCul(int id, string culture)
    {
       var objectContext = ((IObjectContextAdapter)this).ObjectContext;

       var parameters = new List<ObjectParameter>();
       parameters.Add(new ObjectParameter("Id", id));
       parameters.Add(new ObjectParameter("Culture", culture));

       return objectContext.CreateQuery<string>("EntityModels.Store.GetContentByIdAndCul(@Id, @Culture)", parameters.ToArray())
            .Execute(MergeOption.NoTracking)
            .FirstOrDefault();
    }
}

使用标量值函数

客户端代码:

using (var context = new MyEntities())
{
    int id = 1;
    string culture = "fr-FR";
    string result = null;

    result = context.GetContentByIdAndCul(id, culture);
}

7
投票

直到今天,实体框架还不支持生成对标量函数的调用。 但是,您可以在 DbContext 类中编写这样的自定义方法来解决问题:

public partial class YouDbContext
{
    [DbFunction("YouDbContext.Store", "YourScalarFunction")]
    public string YourScalarFunction(string parameter)
    {
        var lObjectContext = ((IObjectContextAdapter)this).ObjectContext;

        return lObjectContext.
            CreateQuery<string >(
                "YouDbContext.Store.YourScalarFunction", 
                new ObjectParameter("parameterName", parameter)).
            Execute(MergeOption.NoTracking).
            FirstOrDefault();
    }
}

6
投票

为 YOURMODEL.Context.cs 创建一个分部类:

public partial class YOUREntities : DbContext

[DbFunction("YOURModel.Store", "YOURSCALARFUNCTION")]
        public string YOURSCALARFUNCTION(string PARAMETER)
        {
            List<ObjectParameter> parameters = new List<ObjectParameter>(3);
            parameters.Add(new ObjectParameter("PARAMETER", PARAMETER));
            var lObjectContext = ((IObjectContextAdapter)this).ObjectContext;
            var output = lObjectContext.
                 CreateQuery<string>("YOURMODEL.Store.YOURSCALARFUNCTION(@PARAMETER)", parameters.ToArray())
                .Execute(MergeOption.NoTracking)
                .FirstOrDefault();
            return output;
        }

确保您已将函数添加到 YOURMODEL.EDMX,应该是这样的:

<Function Name="YOURSCALARFUNCTION" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="true" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo" ReturnType="nvarchar(max)">
          <Parameter Name="PARAMETER" Type="nvarchar(max)" Mode="In" />
        </Function>
© www.soinside.com 2019 - 2024. All rights reserved.