2016-08-09 4 views
0
.

. Мы знаем, что нам не нужно настраивать отношения «один ко многим», используя «Аннотации данных», отношения «один ко многим», настроенные по соглашению.Код EF сначала. Определите свойство отношений «один ко многим» для заданного типа.

В следующем примере ICollection<Student> Students это свойство отношения

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

Так что мой вопрос, как я могу обнаружить отношения propertys для данного типа? Моя цель состоит в том, чтобы проверить значение свойства и сколько элементов содержит

Что-то вроде этого:

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) 
{ 
    // ... 
} 

ответ

1

В простейшей форме (не принимая во внимание любые пользовательские атрибуты или пользовательские сопоставления). Вы можете сделать это:

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

Использование:

var oneToManyProps = GetOneToManyRelationships<Standard>(); 

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

Выход:

Students 

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

+0

В соответствии с соглашением другой тип не может иметь Свойство этого типа, другой тип может иметь только id Свойство. – codeDom

+0

@codeDom вы можете следовать той же логике, чтобы проверить, существует ли свойство с именем 'ClassName + Id' в обоих типах, если первая проверка не удалась. – user3185569

+0

@codeDom проверить обновленный ответ. – user3185569

0

Вы можете .GetProperties() первым, а затем цикл по списку свойств.

 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: В моем примере TryGetOneToManyRelationshipsPropertys является object кстати. Таким образом, вы можете использовать свой giveninstances.

+0

Вы не ответили, как я узнаю, какое свойство представляет отношения. – codeDom

+0

Вы имеете в виду, что пытаетесь выяснить свойство отношения, не зная сама модель данных? – uTeisT

+0

Нет, TryGetOneToManyRelationshipsPropertys принимает два параметра, тип и DbContext. – codeDom