Cha*_*ice 8 .net c# entity-framework
我试图找到一种方法从IEdmEntity到实体框架中的CLR类型.从转换到ObjectContext来获取元数据.我正在使用DataSpace.OCSpace来访问映射.我相信这是正确的,但我可能有错误的DataSpace,即使在这个博客http://blogs.msdn.com/b/alexj/archive/2009/04/之后,DataSpaces也不清楚我的脑袋里做了什么.03/tip-10-understanding-entity-framework-jargon.aspx.
最后我得到了System.Data.Entity.Core.Mapping.MappingBase对象,这些对我来说没什么用.从调试器看起来我可以访问我想要的内容,但这些类被标记为内部,我无法强制转换它们.
我是不是太难了,或者没有办法从实体框架中的IEdmModel回到它映射到的CLR类型?
添加代码以尝试使我更清楚我正在使用并尝试离开
public Type GetIEdmEntityTypeToClrType(IEdmEntityTypeReference edmEntityType, DbContext context)
{
var metadata = ((IObjectContextAdapter)context).ObjectContext.MetadataWorkspace;
var fullname = edmEntityType.EntityDefinition().FullName();
EntityType entityType;
if (metadata.TryGetItem(fullname, DataSpace.CSSpace, out entityType))
{
//doesn't hit
}
if (metadata.TryGetItem(fullname, DataSpace.CSpace, out entityType))
{
//hits but can't get access to CLR Type that it's mapped too.
}
if (metadata.TryGetItem(fullname, DataSpace.OCSpace, out entityType))
{
//doesn't hit
}
if (metadata.TryGetItem(fullname, DataSpace.OSpace, out entityType))
{
//doesn't hit
}
if (metadata.TryGetItem(fullname, DataSpace.SSpace, out entityType))
{
//doesn't hit
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
您在问题和答案中提到的IEdm*接口本身并未由Entity Framework使用(EF6 NuGet包没有Microsoft.Data.Edm依赖项),但主要用于OData服务元数据(CSDL).由于在OData CSDL中声明的实体不一定映射到任何特定的CLR类,因此您只能间接找到它们的CLR类型.(我认为这种混淆是为什么安德鲁的EF专用答案假设你有权访问EntityObject.)
幸运的是,当通过OData呈现EF实体时,OData服务和EF模型的CSDL中的实体的全名之间通常存在1:1的对应关系.假设是这种情况,您可以edmEntityType.FullName像上面那样使用搜索,但是您必须首先EntityType从ObjectContext元数据中获取相应的EF .
DataSpace.OCSpacein MetadataWorkspace是寻找映射的合理位置,因为那是存储Object Space < - > Conceptual Space映射的地方.但正如您所发现的,虽然EF6的映射API应该是公开的,但ObjectTypeMapping其相关类仍然标记为internal:(
然而,事实证明你不需要对内部OCSpace类做任何丑陋的反思黑客攻击!您可以直接从'hit'获取映射的CLR类型,CSpace如下所示:
var clrTypeMetadataPropName = @"http://schemas.microsoft.com/ado/2013/11/edm/customannotation:ClrType";
var clrType = (Type)
((IObjectContextAdapter)context).ObjectContext
.MetadataWorkspace
.GetItems<EntityType>(DataSpace.CSpace)
.Single(s => s.FullName == edmEntityType.FullName())
.MetadataProperties
.Single(p => p.Name == clrTypeMetadataPropName )
.Value;
Run Code Online (Sandbox Code Playgroud)
当然,它使用'内部'ClrType自定义注释键魔术字符串,但一切都是通过当前的公共API完成的.我认为,除非映射API的其余部分公开,否则您可以获得"正式"解决方案.
我假设您使用的是实体框架 6,其中映射 API 不公开。请查看新版本的 Entity Framework 6.1 RTM:
http://blogs.msdn.com/b/adonet/archive/2014/03/17/ef6-1-0-rtm-available.aspx
更具体地说,是公共映射 API 功能:
https://entityframework.codeplex.com/wikipage?title=Public%20Mapping%20API
您应该使用metadataWorkspace来获取有关实体框架类型及其映射的信息,例如实体的所有简单属性及其CLR类型都可以像这样检索:
EntityObject entity = null; //your entity
MetadataWorkspace metadataWorkspace = dataContext.MetadataWorkspace;
Type currentEntityType = entity.GetType();
EntityType entityType = metadataWorkspace.GetItem<EntityType>(currentEntityType.FullName, DataSpace.OSpace);
var simpleProperties = entityType.Properties.Where(p => p.DeclaringType == entityType && p.TypeUsage.EdmType is SimpleType);
foreach (EdmProperty simpleProperty in simpleProperties)
{
Console.WriteLine(string.Format("Name: {0} Type: {1}", simpleProperty.Name,simpleProperty.TypeUsage));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2836 次 |
| 最近记录: |