функции, определяемые моделью, по-прежнему поддерживаются в EF6?

функции, определяемые моделью, обсуждаются здесь:

они поддерживаются EF6.1.2?

Я просматриваю материалы Edm/DbModel и не могу понять, где должен анализироваться элемент «Function» в csdl, потому что он не попадает в EdmModel (EdmModel.AddItem( EdmFunction) не вызывается)

ExpressionConverter.FindFunction просматривает EdmModel._functions, а _functions добавляется только с помощью EdmModel.AddItem(EdmFunction) и вызывается только методом расширения EdmModelExtensions.AddFunction(), и я не могу найти нигде в исходном коде EntityFramework, который вызывает эту функцию . Я должен упустить что-то простое...

больше: я отказался от определения функции в edmx, и теперь я программно создаю свою EdmFunction и добавляю ее в собственный метод IConceptualModelConvention.Apply():

    class CustomFunctionConvention : IConceptualModelConvention<EdmModel>
    {
        public void Apply(EdmModel item, DbModel model)
        {
            var functionPayload = new EdmFunctionPayload () {
                CommandText = "CAST (strValue AS int)",
                Parameters = new [] {
                    FunctionParameter.Create("strValue", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String).GetEdmPrimitiveType(), ParameterMode.In),
                },
                ReturnParameters = new [] {
                    FunctionParameter.Create("ReturnValue", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32).GetEdmPrimitiveType(), ParameterMode.ReturnValue),
                },
                IsComposable = true,
            };

            var function = EdmFunction.Create("ParseInt", "MyNamespace", DataSpace.CSpace, functionPayload, null);
            model.ConceptualModel.AddItem(function);
        }
    }

но теперь я получаю кучу ошибок схемы в EdmItemCollection.LoadItems() :

Schema specified is not valid. Errors:
(0,0) : error 0005: The 'Aggregate' attribute is not allowed.
(0,0) : error 0005: The 'BuiltIn' attribute is not allowed.
(0,0) : error 0005: The 'NiladicFunction' attribute is not allowed.
(0,0) : error 0005: The 'IsComposable' attribute is not allowed.
(0,0) : error 0005: The 'ParameterTypeSemantics' attribute is not allowed.
(0,0) : error 0005: The 'Schema' attribute is not allowed.
(0,0) : error 0005: The 'Mode' attribute is not allowed.

person Spongman    schedule 08.04.2015    source источник
comment
возможно, это может помочь: stackoverflow.com/a/29539227/1236044   -  person jbl    schedule 09.04.2015
comment
не совсем, это для функций, определенных sql. я пытаюсь использовать функции, определяемые моделью. другой зверь.   -  person Spongman    schedule 09.04.2015
comment
Конечно, они прекрасно работают с EF Designer. msdn.microsoft.com/en-us /library/vstudio/ Но я думаю, что ваш вопрос касается Code First, а не Database/Model First.   -  person Carl Prothman    schedule 05.05.2015


Ответы (1)


Кажется, функции, определенные моделью, можно использовать в первую очередь с кодом. Вот версия для вашего ParseInt примера:

namespace EfTestModelFunctions
{
    public class CustomFunctionConvention : IConceptualModelConvention<EdmModel>
    {
        public void Apply(EdmModel item, DbModel model)
        {
            var functionParseInt = new EdmFunctionPayload()
            {
                CommandText = String.Format("CAST(strValue AS {0})", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32)),
                Parameters = new[] {
                    FunctionParameter.Create("strValue", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), ParameterMode.In),
                },

                ReturnParameters = new[] {
                    FunctionParameter.Create("ReturnValue", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32), ParameterMode.ReturnValue),
                },
                IsComposable = true
            };

            var function = EdmFunction.Create("ParseInt", model.ConceptualModel.EntityTypes.First().NamespaceName, DataSpace.CSpace, functionParseInt, null);
            model.ConceptualModel.AddItem(function);
        }
    }

    public class RootDataContext : DbContext
    {
        public RootDataContext()
            : base("Data Source=******")
        {
            Database.SetInitializer(new NullDatabaseInitializer<RootDataContext>());
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Conventions.Add<CustomFunctionConvention>();
        }

        public DbSet<RootEntity> Roots { get; set; }

        // declare the function with the Context's NameSpace
        [DbFunction("EfTestModelFunctions", "ParseInt")]
        public static int ParseInt(string value)
        {
            throw new NotImplementedException();
        }
    }
}

тогда использование будет:

var query = ctx.Roots.Where(r => RootDataContext.ParseInt(r.StringProperty)==123);

Кроме того, кажется, что есть проблема, когда задействована миграция/инициализация базы данных. См. раздел UpForGrabs: Разблокируйте создание определяемых моделью функций в соглашениях о моделях.

person jbl    schedule 12.04.2015
comment
Благодарю. к сожалению, я использую модель .edmx, и этот метод определения функции приводит к ошибкам загрузки модели. эта поломка должна быть своего рода регрессом, верно? «потому что ссылки выше, казалось бы, указывают на то, что это работало для некоторых людей в свое время... - person Spongman; 14.04.2015
comment
@jbl кажется, это то, что мне нужно, но при создании sql я сталкиваюсь с EntitySqlException. С сообщением Недопустимый синтаксис запроса. Рядом с ключевым словом «AS» — есть идеи, почему это может происходить? - person IEnjoyEatingVegetables; 15.07.2020