Gor*_*vic 17 metadata ef-code-first entity-framework-5
我有使用EF-CodeFirst 5的应用程序(dll ver 4.4.0.0,在.net 4.0上).
我需要能够读取实体元数据,以便我可以为给定的条目类型获取以下信息:
我可以通过在属性列表上编写foreach循环来获取此信息,然后通过依赖所有虚拟引用来"识别"它们,但我觉得这不是"正确的"方式.我知道EdmxWriter可以提供xml格式的信息,但它是通过访问不能公开访问的InternalContext来实现的,我想直接获得强类型列表/数组,而不使用那个xml.我应该使用哪种API(如果有这样的API,似乎我找不到它)?
NSG*_*aga 26
Gorane,这应该让你开始...
(我没有玩过多少 - 在调试器中需要一些实验来查看哪些属性/信息以及如何获得它)
using (var db = new MyDbContext())
{
var objectContext = ((IObjectContextAdapter)db).ObjectContext;
var container = objectContext.MetadataWorkspace.GetEntityContainer(objectContext.DefaultContainerName, DataSpace.CSpace);
foreach (var set in container.BaseEntitySets)
{
// set.ElementType.
foreach (var metaproperty in set.MetadataProperties)
{
// metaproperty.
}
}
// ...or...
var keyName = objectContext
.MetadataWorkspace
.GetEntityContainer(objectContext.DefaultContainerName, DataSpace.CSpace)
.BaseEntitySets
.First(meta => meta.ElementType.Name == "Question")
.ElementType
.KeyMembers
.Select(k => k.Name)
.FirstOrDefault();
}
Run Code Online (Sandbox Code Playgroud)
更具体地......
foreach (var set in container.BaseEntitySets)
{
var dependents = ((EntitySet)(set)).ForeignKeyDependents;
var principals = ((EntitySet)(set)).ForeignKeyPrincipals;
var navigationProperties = ((EntityType)(set.ElementType)).NavigationProperties;
foreach (var nav in navigationProperties)
{
// nav.RelationshipType;
}
}
Run Code Online (Sandbox Code Playgroud)
某些属性似乎不是被暴露在"公众",所以你需要使用反射 - 或找一些更聪明的方式 - 但信息的一个很好的协议是在那里.
以及这些链接中的更多信息......
编辑:使用您的navigationProperties列表作为起点,我得到了我需要的一切,如下所示:
ManyToManyReferences = navigationProperties.Where(np =>
np.FromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many &&
np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)
.Select(np => Extensions.CreateLambdaExpression<TEntity>(np.Name))
.ToList();
OneToManyReferences = navigationProperties.Where(np =>
(np.FromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.One ||
np.FromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.ZeroOrOne) &&
np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)
.Select(np => Extensions.CreateLambdaExpression<TEntity>(np.Name))
.ToList();
ManyToOneReferences = navigationProperties.Where(np =>
np.FromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many &&
(np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.One ||
np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.ZeroOrOne))
.Select(np => Extensions.CreateLambdaExpression<TEntity>(np.Name))
.ToList();
OneToOneReferences = navigationProperties.Where(np =>
np.FromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.One &&
np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.One)
.Select(np => Extensions.CreateLambdaExpression<TEntity>(np.Name))
.ToList();
Run Code Online (Sandbox Code Playgroud)
CreateLambdaExpression方法不是我的礼貌,积分转到Jon Skeet,代码是在这个答案的帮助下创建的
这是我的CreateLambdaExpression方法:
public static Expression<Func<TEntity, object>> CreateLambdaExpression<TEntity>(string propertyName)
{
ParameterExpression parameter = Expression.Parameter(typeof (TEntity), typeof (TEntity).Name);
Expression property = Expression.Property(parameter, propertyName);
return Expression.Lambda<Func<TEntity, object>>(property, new[] {parameter});
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9745 次 |
| 最近记录: |