【问题标题】:are model-defined functions still supported in EF6?EF6 是否仍支持模型定义的函数?
【发布时间】:2015-06-12 18:43:34
【问题描述】:

此处讨论模型定义的函数:

EF6.1.2 是否支持这些?

我正在逐步浏览 Edm/DbModel 的内容,但我终其一生都无法确定应该解析 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.

【问题讨论】:

标签: entity-framework ado.net ado.net-entity-data-model


【解决方案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: Unblock creation of model defined functions in model conventions

【讨论】:

  • 谢谢。不幸的是,我使用的是 .edmx 模型,这种定义函数的方法会导致模型加载错误。这被打破一定是某种回归,对吧? '因为上面的链接似乎表明这一次对某些人有效......
  • @jbl 这似乎是我需要的,但是在生成 sql 时,我遇到了 EntitySqlException。带有消息“查询语法无效。靠近关键字'AS'” - 知道为什么会发生这种情况吗?
猜你喜欢
  • 2017-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-21
  • 2018-08-02
  • 2018-09-02
  • 2021-01-12
相关资源
最近更新 更多