2016-08-09 42 views
0

Wir wissen, dass wir für 1: n-Beziehungen keine Datenkonventionen verwenden müssen.EF-Code zuerst - Erkennen der 1: n-Beziehungen für den angegebenen Typ

Im folgenden Beispiel ICollection<Student> Students ist eine Beziehung Eigenschaft

public class Student 
{ 
    public Student() { } 

    public int StudentId { get; set; } 
    public string StudentName { get; set; } 

    public virtual Standard Standard { get; set; } 
} 

public class Standard 
{ 
    public Standard() 
    { 
     Students = new List<Student>(); 
    } 
    public int StandardId { get; set; } 
    public string Description { get; set; } 

    public virtual ICollection<Student> Students { get; set; } 
} 

Also meine Frage ist, wie kann ich eine Beziehung propertys für einen bestimmten Typ erkennen? Mein Ziel ist es, den Wert der Immobilie zu testen und wie viele Elemente enthält

So etwas:

static void Test(object givenInstanse) 
{ 
    foreach (PropertyInfo p in TryGetOneToManyRelationshipsPropertys(typeof(givenInstanse), dc)) 
    { 
     var val = (ICollection)p.GetValue(givenInstanse); 
     Console.WriteLine(val.Count); 
    } 
} 

static IEnumerable<PropertyInfo> TryGetOneToManyRelationshipsPropertys(Type t, DbContext dc) 
{ 
    // ... 
} 

Antwort

1

In seiner einfachsten Form (Keine Berücksichtigung von benutzerdefinierten Attributen oder benutzerdefinierten Zuordnungen). Sie können dies tun:

IEnumerable<PropertyInfo> GetOneToManyRelationships<T>() 
{ 
    var collectionProps = from p in typeof(T).GetProperties() 
          where p.PropertyType.IsGenericType 
           && p.PropertyType.GetGenericTypeDefinition() 
                == typeof(ICollection<>) 
          select p; 

    foreach (var prop in collectionProps) 
    { 
     var type = prop.PropertyType.GetGenericArguments().First(); 

     // This checks if the other type has a One Property of this Type. 
     bool HasOneProperty = type.GetProperties().Any(x => x.PropertyType == typeof(T)); 

     if(!HasOneProperty) 
     { 
      string pkName = typeof(T).Name + "Id"; 

      HasOneProperty = type.GetProperties().Any(x => x.Name.Equals(pkName, 
                 StringComparison.OrdinalIgnoreCase)); 
     } 

     if (HasOneProperty) 
     { 
      yield return prop; 
     } 
    } 
} 

Verbrauch:

var oneToManyProps = GetOneToManyRelationships<Standard>(); 

foreach(var prop in oneToManyProps) 
{ 
    Console.WriteLine(prop.Name); 
} 

Ausgang:

Students 

Sie können diese erweitern für Attribute auf Eigenschaften markiert zu überprüfen, aber ich werde es dich verlassen wie es außerhalb des Bereichs Ihrer Frage ist.

+0

Gemäß der Konvention kann der andere Typ keine Eigenschaft dieses Typs haben, ein anderer Typ kann nur eine ID-Eigenschaft haben. – codeDom

+0

@codeDom Sie können der gleichen Logik folgen, um zu überprüfen, ob eine Eigenschaft mit dem Namen 'ClassName + Id' in beiden Typen vorhanden ist, wenn die erste Prüfung fehlgeschlagen ist. – user3185569

+0

@codeDom überprüfen Sie die aktualisierte Antwort. – user3185569

0

können Sie .GetProperties() erste und dann die Schleife durch Objektliste.

 List<System.Reflection.PropertyInfo> propertyInfoList = TryGetOneToManyRelationshipsPropertys.GetType().GetProperties().ToList(); 

     foreach (System.Reflection.PropertyInfo property in propertyInfoList) 
     { 
      object propertyValue = property.GetValue(TryGetOneToManyRelationshipsPropertys); 
      if (propertyValue == null) 
       propertyValue = string.Empty; 
     } 

* Edit: In meinem Beispiel TryGetOneToManyRelationshipsPropertys ist object btw. Also, Sie könnten stattdessen Ihre giveninstances verwenden.

+0

Sie haben nicht geantwortet, woher ich weiß, welche Eigenschaft die Beziehung darstellt. – codeDom

+0

Sie meinen, Sie versuchen, die Beziehungseigenschaft herauszufinden, ohne das Datenmodell selbst zu kennen? – uTeisT

+0

Nein, TryGetOneToManyRelationshipsProperty verwendet zwei Parameter, den Typ und den DbContext. – codeDom