【问题标题】:Error 6046: Unable to generate function import return type of the store function错误 6046:无法生成存储函数的函数导入返回类型
【发布时间】:2014-08-01 09:32:13
【问题描述】:

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

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

Error 6046: Unable to generate function import return type of the store function 'GetContentByIdAndCul'.
The store function will be ignored and the function import will not be generated.   ..\EntityModels.edmx

我的函数 tsql 是:

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

【问题讨论】:

    标签: linq entity-framework sql-function


    【解决方案1】:

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

    这是一个经过测试的解决方案,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>
    

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

    使用部分类机制(https://msdn.microsoft.com/en-us/library/wa80x488%28v=vs.120%29.aspx)创建新的源文件并将代码添加到自动生成的DbContext 类(比如她的名字是MyEntities

    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);
    }
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        直到今天,实体框架还不支持生成对标量函数的调用。 但是,您可以在 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();
            }
        }
        

        【讨论】:

        • 它的 2019 EF 6.3 仍然没有得到支持。所以我回到了 Linq to SQL
        猜你喜欢
        • 2014-07-20
        • 2019-12-12
        • 2015-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多