Ошибка 6046: Невозможно сгенерировать функцию возврата типа импорта функции хранилища

У меня есть скалярнозначная функция в моей базе данных sql.

Я получаю эту ошибку при импорте этой функции в модель Entity Framework:

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 [email protected] AND (CUL.Contents.Culture = LOWER(@Culture) 
            OR CUL.Contents.Culture = LOWER(SUBSTRING(@Culture,1,2)))   
return @Result      
END

Ответ 1

Предшествующие ответы показывают хороший способ решить проблему, но никто не работает в реальной жизни.

Здесь проверенное решение с Entity Framework 6, которое работает для меня. Поэтому он должен работать для вас.

Импортировать скалярнозначную функцию

Импортируйте свою скалярную функцию [FRM].[GetContentByIdAndCul] в вашу модель Entity Framework. Он автоматически создает соответствующую запись в модели хранения вашего файла 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), используя механизм Partial class (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);
}

Ответ 2

До сегодняшнего дня инфраструктура сущности не поддерживает генерации вызовов для скалярных функций. Но вы можете решить проблему, выписывая собственный метод, подобный этому, в вашем классе 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();
    }
}

Ответ 3

Создайте частичный класс для 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>