Я знаю, что это может быть старый вопрос, но я буду оставьте решение здесь на всякий случай. Как только вы получили 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);
}
UPDATE: быть более конкретными и получить внешний ключ для соответствующего объекта определенного типа вы можете сделать следующее:
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;
}
У меня есть поле на другую таблицу, если я предполагаю, что это это PK этой таблицы: 'var ForeignField = otherTableType.KeyMembers.Single(). Name' – MikeW
Этот подход не может, однако, дать поле в локальной таблице (даже если посмотреть на ограничение FK с другого конца), поскольку нет убедитесь, что поле является ПК на локальном столе (и вообще это не будет), я застрял в том, куда идти отсюда ... – MikeW