2015-02-17 2 views
1

Я пытаюсь определить внешние ключи на лицо в качестве EF кода первого сценария,получить список ограничений внешних ключей для EF кода первого объекта

код, который я до сих пор говорит мне таблицы, в которой внешние ключи связаны (или, скорее, навигационные свойства), но мне нужны свойства, которые представляют собой отношения на обоих концах (простая строка будет делать):

public void DetermineForiegnKeys<T>() 
{ 
    entitySet = ((IObjectContextAdapter)dbbuilder.s200).ObjectContext.CreateObjectSet<T>().EntitySet; 
    var nps = entitySet.Value.ElementType.NavigationProperties; 

    foreach (var np in nps) 
    { 
     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 = false; 
     } 
     //how do I get the property names on this entity (T) and the other?? 
     // just the IDs, not the virtual properties... 
    } 
} 
+0

У меня есть поле на другую таблицу, если я предполагаю, что это это PK этой таблицы: 'var ForeignField = otherTableType.KeyMembers.Single(). Name' – MikeW

+0

Этот подход не может, однако, дать поле в локальной таблице (даже если посмотреть на ограничение FK с другого конца), поскольку нет убедитесь, что поле является ПК на локальном столе (и вообще это не будет), я застрял в том, куда идти отсюда ... – MikeW

ответ

1

Я знаю, что это может быть старый вопрос, но я буду оставьте решение здесь на всякий случай. Как только вы получили 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; 
} 
+0

Спасибо, что дает мне имя внешних ключей, однако оно не предоставляет тип для другой таблицы или поля, которое связано с этой другой таблицей. – MikeW

+0

@MikeW, поэтому вы хотите фильтровать navProperties по типу T и получить внешний ключ, который указывает на объект типа T? –

+0

@MikeW Я обновил ответ, чтобы рассмотреть еще один сценарий –

Смежные вопросы