Ale*_*xey 27 c# entity-framework sql-function ef-code-first entity-framework-6
我想将Entity Framework 6集成到我们的系统中,但是有问题.
问题是:
我不能通过像[Table],[Column]这样的属性来映射函数.只有1个属性可用[DbFunction],它需要*.edmx文件.
我可以在*.edmx文件中映射函数,但这意味着我不能使用实体的属性映射:[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;
}
}
Run Code Online (Sandbox Code Playgroud)
但有例外:
在模型生成期间检测到一个或多个验证错误:
Edm.String: : The namespace 'String' is a system namespace and cannot be used by other schemas. Choose another namespace name.
Run Code Online (Sandbox Code Playgroud)
问题出在"edmType"变量中.我无法正确创建函数的ReturnType.任何人都可以建议我如何在模型中添加功能?添加功能的界面是暴露的,所以它应该能够做到,但是在这种情况下web中没有信息.可能有人知道Entity Framework团队何时会为Line To Sql这样的函数实现属性映射.
EF版本:6.0.0-beta1-20521
谢谢!
是的,这适合我.但仅适用于标量函数.我也需要map函数,它返回IQueryable:
IQueryable<T> MyFunction()
Run Code Online (Sandbox Code Playgroud)
其中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()));
}
Run Code Online (Sandbox Code Playgroud)
但仍然没有运气:
model.Compile(); // ERROR
Run Code Online (Sandbox Code Playgroud)
有可能吗?可能步骤不对?可能会在EF 6.1上添加支持.任何信息都非常有用.
谢谢!
Ath*_*ari 15
尚未尝试过,但Entity Framework 6.1包含公共映射API.Moozzyk 使用这一新功能为EntityFramework CodeFirst实现了Store Functions.
这是代码的样子:
public class MyContext : DbContext
{
public DbSet<Customer> Customers { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Add(new FunctionsConvention<MyContext>("dbo"));
}
[DbFunction("MyContext", "CustomersByZipCode")]
public IQueryable<Customer> CustomersByZipCode(string zipCode)
{
var zipCodeParameter = zipCode != null ?
new ObjectParameter("ZipCode", zipCode) :
new ObjectParameter("ZipCode", typeof(string));
return ((IObjectContextAdapter)this).ObjectContext
.CreateQuery<Customer>(
string.Format("[{0}].{1}", GetType().Name,
"[CustomersByZipCode](@ZipCode)"), zipCodeParameter);
}
public ObjectResult<Customer> GetCustomersByName(string name)
{
var nameParameter = name != null ?
new ObjectParameter("Name", name) :
new ObjectParameter("Name", typeof(string));
return ((IObjectContextAdapter)this).ObjectContext.
ExecuteFunction("GetCustomersByName", nameParameter);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 3
您可以使用辅助方法从原始类型获取 Store 类型:
public static EdmType GetStorePrimitiveType(DbModel model, PrimitiveTypeKind typeKind)
{
return model.ProviderManifest.GetStoreType(TypeUsage.CreateDefaultTypeUsage(
PrimitiveType.GetEdmPrimitiveType(typeKind))).EdmType;
}
Run Code Online (Sandbox Code Playgroud)
在您的示例中,您必须更改返回参数的类型:
var edmType = GetStorePrimitiveType(model, PrimitiveTypeKind.String);
Run Code Online (Sandbox Code Playgroud)
我在这里找到了我需要的帮助:
http://entityframework.codeplex.com/discussions/466706
归档时间: |
|
查看次数: |
30762 次 |
最近记录: |