我想将 Entity Framework 6 集成到我们的系统中,但是有问题。
- 我想使用代码优先。由于其他原因,我不想使用 Database First *.edmx 文件。
- 我使用属性映射 [Table]、[Column] 这很好用
- 数据库有许多用户定义的函数,我需要在 Linq To Entities 查询中使用它们。
问题是:
我无法通过 [Table]、[Column] 等属性映射函数。只有 1 个属性可用 [DbFunction],它需要 *.edmx 文件。
我可以在 *.edmx 文件中进行函数映射,但这意味着我不能对实体使用属性映射:[表]、[列]。*.edmx 或属性中的映射必须是完整的。
我尝试通过以下代码创建 DbModel 并添加功能:
public static class Functions
{
[DbFunction("CodeFirstNamespace", "TestEntity")]
public static string TestEntity()
{
throw new NotSupportedException();
}
}
public class MyContext : DbContext, IDataAccess
{
protected MyContext (string connectionString)
: base(connectionString, CreateModel())
{
}
private static DbCompiledModel CreateModel()
{
var dbModelBuilder = new DbModelBuilder(DbModelBuilderVersion.Latest);
dbModelBuilder.Entity<Warehouse>();
var dbModel = dbModelBuilder.Build(new DbProviderInfo("System.Data.SqlClient", "2008"));
var edmType = PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String);
var payload =
new EdmFunctionPayload
{
Schema = "dbo",
ParameterTypeSemantics = ParameterTypeSemantics.AllowImplicitConversion,
IsComposable = true,
IsNiladic = false,
IsBuiltIn = false,
IsAggregate = false,
IsFromProviderManifest = true,
StoreFunctionName = "TestEntity",
ReturnParameters =
new[]
{
FunctionParameter.Create("ReturnType", edmType, ParameterMode.ReturnValue)
}
};
var function = EdmFunction.Create("TestEntity", "CodeFirst", DataSpace.CSpace, payload, null);
dbModel.DatabaseMapping.Model.AddItem(function);
var compiledModel = dbModel.Compile(); // Error happens here
return compiledModel;
}
}
但有例外:
在模型生成期间检测到一个或多个验证错误:
Edm.String: : The namespace 'String' is a system namespace and cannot be used by other schemas. Choose another namespace name.
问题出在“edmType”变量中。我无法为函数正确创建 ReturnType。有人可以建议我如何将功能添加到模型中吗?添加功能的接口是暴露的,所以应该可以做,但是网上没有关于这种情况的信息。可能有人知道 Entity Framework 团队何时会为 Line To Sql 之类的函数实现属性映射。
EF 版本:6.0.0-beta1-20521
谢谢!
是的,这对我有用。但仅适用于标量函数。我还需要返回 IQueryable 的 map 函数:
IQueryable<T> MyFunction()
其中 T 是 EntityType 或 RowType 或任何类型。我根本无法做到这一点(EF 版本是 6.0.2-21211)。我认为这应该以这种方式工作:
private static void RegisterEdmFunctions(DbModel model)
{
var storeModel = model.GetStoreModel();
var functionReturnValueType = storeModel.EntityTypes.Single(arg => arg.Name == "MyEntity").GetCollectionType();
var payload =
new EdmFunctionPayload
{
IsComposable = true,
Schema = "dbo",
StoreFunctionName = "MyFunctionName",
ReturnParameters =
new[]
{
FunctionParameter.Create("ReturnValue", functionReturnValueType, ParameterMode.ReturnValue)
},
Parameters =
new[]
{
FunctionParameter.Create("MyFunctionInputParameter", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32), ParameterMode.In)
}
};
storeModel.AddItem(EdmFunction.Create(
payload.StoreFunctionName,
"MyFunctionsNamespace",
DataSpace.SSpace,
payload,
payload.Parameters.Select(arg => MetadataProperty.Create(arg.Name, arg.TypeUsage, null)).ToArray()));
}
但仍然没有运气:
model.Compile(); // ERROR
有没有可能?大概步骤不对吧?可能会在 EF 6.1 中添加支持。任何信息都会非常有用。
谢谢!