模型定义的函数在这里讨论:
是否支持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.
答案 0 :(得分:2)
看来,模型定义的函数首先可以使用代码。以下是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