C# 获取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

我试图确定EF代码优先方案中实体上的外键

到目前为止,我的代码告诉我与外键相关的表(或者更确切地说是导航属性),但我需要在任意一端表示关系的属性(一个简单的字符串即可):

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;
}