Я хочу интегрировать Entity Framework 6 в нашу систему, но проблема.
- Я хочу использовать Code First. Я не хочу использовать файл Database First *.edmx по другим причинам.
- Я использую сопоставление атрибутов [Таблица], [Колонка], и это отлично работает
- В базе данных есть много пользовательских функций, и мне нужно использовать их в запросе Linq To Entities.
Проблема:
Я не могу сопоставить функцию с помощью атрибута, например [Таблица], [Столбец]. Доступен только 1 атрибут [DbFunction], для которого требуется *.edmx файл.
Мне нужно иметь отображение функций в файле *.edmx, но это означает, что я не могу использовать сопоставление атрибутов для Entities: [Table], [Column]. Сопоставление должно быть заполнено в *.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:
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. Любая информация будет очень полезна.
Спасибо!