C# 获取EF代码第一个实体的外键约束列表
我试图确定EF代码优先方案中实体上的外键 到目前为止,我的代码告诉我与外键相关的表(或者更确切地说是导航属性),但我需要在任意一端表示关系的属性(一个简单的字符串即可):C# 获取EF代码第一个实体的外键约束列表,c#,entity-framework,C#,Entity Framework,我试图确定EF代码优先方案中实体上的外键 到目前为止,我的代码告诉我与外键相关的表(或者更确切地说是导航属性),但我需要在任意一端表示关系的属性(一个简单的字符串即可): public void determineforegnkeys() { entitySet=((IObjectContextAdapter)dbbuilder.s200).ObjectContext.CreateObjectSet().entitySet; var nps=entitySet.Value.ElementType
public void determineforegnkeys()
{
entitySet=((IObjectContextAdapter)dbbuilder.s200).ObjectContext.CreateObjectSet().entitySet;
var nps=entitySet.Value.ElementType.NavigationProperties;
foreach(np中的var np)
{
var otherTableType=((RefType)np.FromEndMember.TypeUsage.EdmType).ElementType;
var-otherIsFrom=true;
if(otherTableType.Name.Equals(typeof(T.Name))
{
otherTableType=((RefType)np.ToEndMember.TypeUsage.EdmType).ElementType;
otherIsFrom=假;
}
//如何获取此实体(T)和其他实体上的属性名称??
//只有ID,而不是虚拟属性。。。
}
}
我知道这可能是个老问题,但我会在这里留下一个解决方案以防万一。获得NavigationProperty
后,可以使用GetDependentProperties
获取外键列表。棘手的部分是,该方法只返回CSpace类型的键。因此,我们必须将代理类型转换为CSpace类型
public static string[] GetForeignKeys(DbContext context, Type type)
{
StructuralType edmType = GetCSpaceType(context, type);
var members = edmType
.MetadataProperties
.Where(mp => mp.Name == "Members")
.FirstOrDefault();
if (members != null && members.Value != null)
{
List<NavigationProperty> navProps = ((ICollection<EdmMember>)members.Value)
.Where(m => m.BuiltInTypeKind == BuiltInTypeKind.NavigationProperty)
.Cast<NavigationProperty>()
.Where(p =>
((AssociationType)p.RelationshipType).IsForeignKey
)
.ToList();
List<EdmProperty> foreignKeys = navProps
.SelectMany(p => p.GetDependentProperties())
.ToList();
return foreignKeys.Select(p => p.Name).ToArray();
}
return null;
}
private static StructuralType GetCSpaceType(DbContext context, Type type)
{
MetadataWorkspace workspace = ((IObjectContextAdapter)context).ObjectContext.MetadataWorkspace;
EdmType ospaceType = workspace.GetType(type.Name, type.Namespace, DataSpace.OSpace);
return workspace.GetEdmSpaceType((StructuralType)ospaceType);
}
公共静态字符串[]GetForeignKeys(DbContext上下文,类型)
{
StructureType edmType=GetCSpaceType(上下文,类型);
var成员=edmType
.元数据属性
.Where(mp=>mp.Name==“成员”)
.FirstOrDefault();
if(members!=null&&members.Value!=null)
{
列出navProps=((ICollection)members.Value)
.Where(m=>m.BuiltyPekind==BuiltyPekind.NavigationProperty)
.Cast()
.其中(p=>
((AssociationType)p.RelationshipType).IsForeignKey
)
.ToList();
列出外键=导航道具
.SelectMany(p=>p.GetDependentProperties())
.ToList();
返回foreignKeys.Select(p=>p.Name).ToArray();
}
返回null;
}
私有静态StructureType GetCSpaceType(DbContext上下文,类型类型)
{
MetadataWorkspace=((IObjectContextAdapter)上下文).ObjectContext.MetadataWorkspace;
EdmType-ospaceType=workspace.GetType(type.Name、type.Namespace、DataSpace.OSpace);
返回workspace.GetEdmSpaceType((StructuralType)ospaceType);
}
更新:要更具体,并为特定类型的相关实体获取外键,您可以执行以下操作:
public static PropertyInfo GetForeignKey(DbContext context, Type type, Type related)
{
StructuralType edmType = GetCSpaceType(context, type);
StructuralType parentEdmType = GetCSpaceType(context, related);
var members = edmType
.MetadataProperties
.Where(mp => mp.Name == "Members")
.FirstOrDefault();
if (members != null && members.Value != null)
{
List<NavigationProperty> navProps = ((ICollection<EdmMember>)members.Value)
.Where(m => m.BuiltInTypeKind == BuiltInTypeKind.NavigationProperty)
.Cast<NavigationProperty>()
.Where(p =>
((AssociationType)p.RelationshipType).IsForeignKey
)
.ToList();
NavigationProperty navProp = navProps
.FirstOrDefault(p => ((RefType)p.ToEndMember.TypeUsage.EdmType).ElementType.FullName == parentEdmType.FullName);
if (navProp != null)
{
var dependent = navProp.GetDependentProperties().ToList();
if (dependent.Count > 0)
{
return type.GetProperty(dependent[0].Name);
}
}
}
return null;
}
publicstaticpropertyinfo GetForeignKey(DbContext-context,Type-Type,Type-related)
{
StructureType edmType=GetCSpaceType(上下文,类型);
StructureType ParentedType=GetCSpaceType(上下文,相关);
var成员=edmType
.元数据属性
.Where(mp=>mp.Name==“成员”)
.FirstOrDefault();
if(members!=null&&members.Value!=null)
{
列出navProps=((ICollection)members.Value)
.Where(m=>m.BuiltyPekind==BuiltyPekind.NavigationProperty)
.Cast()
.其中(p=>
((AssociationType)p.RelationshipType).IsForeignKey
)
.ToList();
NavigationProperty navProp=navProps
.FirstOrDefault(p=>((RefType)p.ToEndMember.TypeUsage.EdmType).ElementType.FullName==ParentedType.FullName);
如果(navProp!=null)
{
var dependent=navProp.GetDependentProperties().ToList();
如果(dependent.Count>0)
{
返回类型.GetProperty(依赖[0].Name);
}
}
}
返回null;
}
如果我假设另一个表上的字段是该表的主键,则该字段位于该表上:var ForeignField=otherTableType.KeyMembers.Single().Name
但是,这种方法无法在本地表上给出该字段(即使从另一端查看FK约束),因为无法保证该字段是本地表上的主键(通常不会),我一直在想从这里该怎么走……谢谢,这给了我外键的名称,但是它没有提供其他表的类型或链接到其他表上的字段。@MikeW所以你想按类型T筛选navProperties并获取指向类型T的实体的外键?
public static PropertyInfo GetForeignKey(DbContext context, Type type, Type related)
{
StructuralType edmType = GetCSpaceType(context, type);
StructuralType parentEdmType = GetCSpaceType(context, related);
var members = edmType
.MetadataProperties
.Where(mp => mp.Name == "Members")
.FirstOrDefault();
if (members != null && members.Value != null)
{
List<NavigationProperty> navProps = ((ICollection<EdmMember>)members.Value)
.Where(m => m.BuiltInTypeKind == BuiltInTypeKind.NavigationProperty)
.Cast<NavigationProperty>()
.Where(p =>
((AssociationType)p.RelationshipType).IsForeignKey
)
.ToList();
NavigationProperty navProp = navProps
.FirstOrDefault(p => ((RefType)p.ToEndMember.TypeUsage.EdmType).ElementType.FullName == parentEdmType.FullName);
if (navProp != null)
{
var dependent = navProp.GetDependentProperties().ToList();
if (dependent.Count > 0)
{
return type.GetProperty(dependent[0].Name);
}
}
}
return null;
}