在模型中定义的函数在EF6仍支持? [英] are model-defined functions still supported in EF6?
问题描述
模型定义的函数这里讨论:
- https://msdn.microsoft .COM / EN-US /库/ vstudio / dd456857(V = vs.110)的.aspx
- https://msdn.microsoft.com/en-us/library/ dd456812.aspx
- <一个href="http://stackoverflow.com/questions/16737393/entity-framework-6-$c$c-first-function-mapping">Entity框架6 code首先函数映射
- http://www.c-sharpcorner.com/UploadFile / ff2f08 /模型定义的函数/
在这些支持EF6.1.2?
我踩着通过EDM / DbModel之后的东西,我不能为我的生活工作,其中的&lt;功能&GT;在CSDL元素应该被解析,因为它没有把它放入EdmModel(EdmModel.AddItem(EdmFunction)是没有得到所谓的)
防爆pressionConverter.FindFunction看起来EdmModel._functions,并_functions仅受EdmModel.AddItem(EdmFunction)加入而这仅被扩展方法EdmModelExtensions.AddFunction(),我找不到任何地方的的EntityFramework源$ C $ C调用该函数。我必须失去了一些东西简单...
更:我放弃了在定义函数的EDMX,现在我创造我EdmFunction编程和自定义将其添加IConceptualModelConvention.Apply()方法:
类CustomFunctionConvention:IConceptualModelConvention&LT; EdmModel&GT;
{
公共无效申请(EdmModel项目,DbModel之后,模型)
{
VAR functionPayload =新EdmFunctionPayload(){
的CommandText =CAST(strValue中为INT),
参数=新的[] {
FunctionParameter.Create(strValue的,PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String).GetEdmPrimitiveType(),ParameterMode.In)
},
ReturnParameters =新的[] {
FunctionParameter.Create(返回值,PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32).GetEdmPrimitiveType(),ParameterMode.ReturnValue),
},
IsComposable = TRUE,
};
VAR功能= EdmFunction.Create(parseInt函数,myNameSpace对象,DataSpace.CSpace,functionPayload,NULL);
model.ConceptualModel.AddItem(功能);
}
}
但现在我得到的EdmItemCollection.LoadItems()一堆架构错误的:
指定的架构是无效的。错误:
(0,0):错误0005:该汇总属性是不允许的。
(0,0):错误0005:在'内置'属性是不允许的。
(0,0):错误0005:在NiladicFunction'属性是不允许的。
(0,0):错误0005:在IsComposable'属性是不允许的。
(0,0):错误0005:在ParameterTypeSemantics'属性是不允许的。
(0,0):错误0005:该模式属性是不允许的。
(0,0):错误0005:该模式属性是不允许的。
看来,自定义模型功能与code首先使用。这里是一个版本为您 parseInt函数
例如:
命名空间EfTestModelFunctions
{
公共类CustomFunctionConvention:IConceptualModelConvention&LT; EdmModel&GT;
{
公共无效申请(EdmModel项目,DbModel之后,模型)
{
VAR functionParseInt =新EdmFunctionPayload()
{
的CommandText =的String.Format(CAST(strValue的AS {0}),PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32)),
参数=新的[] {
FunctionParameter.Create(strValue的,PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String),ParameterMode.In)
},
ReturnParameters =新的[] {
FunctionParameter.Create(返回值,PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32),ParameterMode.ReturnValue)
},
IsComposable =真
};
VAR功能= EdmFunction.Create(parseInt函数,model.ConceptualModel.EntityTypes.First()NamespaceName,DataSpace.CSpace,functionParseInt,空);
model.ConceptualModel.AddItem(功能);
}
}
公共类RootDataContext:的DbContext
{
公共RootDataContext()
:基地(数据源= ******)
{
Database.SetInitializer(新NullDatabaseInitializer&其中; RootDataContext&GT;());
}
保护覆盖无效OnModelCreating(DbModelBuilder模型构建器)
{
base.OnModelCreating(模型构建器);
modelBuilder.Conventions.Add&其中; CustomFunctionConvention&GT;();
}
公共DbSet&LT; RootEntity&GT;根{获得;组; }
//声明与上下文的命名空间功能
[DbFunction(EfTestModelFunctions,parseInt函数)]
公共静态INT parseInt函数(字符串值)
{
抛出新的NotImplementedException();
}
}
}
使用将为:
VAR的查询= ctx.Roots.Where(R =&GT; RootDataContext.ParseInt(r.StringProperty)== 123);
此外,似乎还有涉及数据库迁移/初始化时的问题。看到 UpForGrabs:模型定义的函数在阻止创建示范公约
model-defined functions are discussed here:
- https://msdn.microsoft.com/en-us/library/vstudio/dd456857(v=vs.110).aspx
- https://msdn.microsoft.com/en-us/library/dd456812.aspx
- Entity Framework 6 Code First function mapping
- http://www.c-sharpcorner.com/UploadFile/ff2f08/model-defined-function/
are these supported by EF6.1.2?
I'm stepping through the Edm/DbModel stuff and I can't for the life of me work out where the <Function> element in the csdl is supposed to be parsed, because it's not making it into the EdmModel (EdmModel.AddItem(EdmFunction) isn't getting called)
ExpressionConverter.FindFunction looks in EdmModel._functions, and _functions is only added to by EdmModel.AddItem(EdmFunction) and that's only called by the extension method EdmModelExtensions.AddFunction(), and I cannot find anywhere in the EntityFramework source code that calls that function. I must be missing something simple...
more: I gave up on defining the Function in the edmx and now I'm creating my EdmFunction programatically and adding it in a custom IConceptualModelConvention.Apply() method:
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);
}
}
but now I'm getting a bunch of schema errors in 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.
It seems, model defined functions are usable with code first. Here is a version for your ParseInt
example :
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();
}
}
}
usage will then be :
var query = ctx.Roots.Where(r => RootDataContext.ParseInt(r.StringProperty)==123);
Also, it seems there is an issue when database migration/initialization is involved. See UpForGrabs: Unblock creation of model defined functions in model conventions
这篇关于在模型中定义的函数在EF6仍支持?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!