2016-08-09 8 views
0

データアノテーションを使用して1対多のリレーションシップを構成する必要はないことがわかっています。次の例ICollection<Student> StudentsEFコード1番目 - 指定された型の1対多リレーションシッププロパティを検出

は、だから私の質問は、私は特定のタイプのために関係propertysを検出することができますどのように、ある

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

関係プロパティですか? 私の目標は、プロパティの値をテストすることであり、それはそのような

何かが含まれているどのように多くの項目:

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最初のチェックに失敗した場合は、同じロジックに従って、クラス名+ 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; 
     } 

*編集:私の例ではTryGetOneToManyRelationshipsPropertysがところでobjectです。だから、代わりにgiveninstancesを使用している可能性があります。

+0

あなたはどのような特性が関係を表しているかをどのように知っているのですか? – codeDom

+0

実際にデータモデルそのものを知らなくてもリレーションプロパティを見つけようとしていますか? – uTeisT

+0

いいえ、TryGetOneToManyRelationshipsPropertysは、typeとDbContextの2つのパラメータをとります。 – codeDom

関連する問題