Spo*_*man 6 ado.net entity-framework ado.net-entity-data-model
这里讨论模型定义的函数:
EF6.1.2 支持这些吗?
我正在逐步完成 Edm/DbModel 的内容,但我一生都无法弄清楚 csdl 中的 <Function> 元素应该在哪里进行解析,因为它没有将其放入 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);
}
}
Run Code Online (Sandbox Code Playgroud)
但现在我在 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.
Run Code Online (Sandbox Code Playgroud)
看来,模型定义的函数首先可以与代码一起使用。这是您的示例的版本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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法将是:
var query = ctx.Roots.Where(r => RootDataContext.ParseInt(r.StringProperty)==123);
Run Code Online (Sandbox Code Playgroud)
另外,涉及数据库迁移/初始化时似乎存在问题。请参阅 UpForGrabs:取消阻止在模型约定中创建模型定义的函数
| 归档时间: |
|
| 查看次数: |
1697 次 |
| 最近记录: |