0

例として次のモデルを使用します。

public class FooModel
{
    public FooModel()
    {
        Bars= new List<BarModel>();
    }

    [ManyToMany]
    public IList<BarModel> Bars{ get; set; }
}
public class BarModel
{
    public int Id { get; set; }
}

List<BarModel>オブジェクトからを推定し、リスト内の各 BarModel からfooModelを構築する必要があります。Dictionary<string, object>


次のオブジェクトを作成するとします。

var fooModel = new FooModel();
var bar1 = new BarModel {Id = 1};
var bar2 = new BarModel {Id = 2};
fooModel.Bars = new List<BarModel>{bar1,bar2};

そして今、属性を持つ Foo 内のすべてのプロパティを取得したいと考えてい[ManyToMany]ます。

// First I call the method and pass in the model
DoSomething(fooModel);
// Next I extract some values (used elsewhere)
public DoSomething<TModel>(IModel model){

    var dbProvider = ...;
    var mapper = new AutoMapper<TModel>();
    var tableName = GetTableName( typeof( TModel ) );

    UpdateJoins( dbProvider, fooModel, tableName, mapper );
}
// Finally I begin dealing with the collection.
private static void UpdateJoins<TModel> ( IDbProvider dbProvider, TModel model, string tableName, IAutoMapper<TModel> mapper ) where TModel : class, new()
{
    foreach (
        var collection in
             model.GetType()
                  .GetProperties()
                  .Where( property => property.GetCustomAttributes( typeof( ManyToManyAttribute ), true ).Any() ) )
    {

        if ( !IsGenericList( collection.PropertyType ) )
            throw new Exception( "The property must be a List" );

        // Stuck Here - pseudo code
        //====================
        foreach (loop the collection)

             var collectionName = ...;  // Bar
             var nestedPropertyName = ...;  // Id
             var rightKey = collectionName + nestedPropertyName; // BarId
             var nestedPropertyValue = ...; // 1

    }
}

上記の例では、属性で装飾されたforeachプロパティが 1 つしかないため、OUTERは 1 回だけ実行されます。FooModel[ManyToMany]

したがってPropertyInfo propertyList<BarModel>

foreach上記の INNER を実行して必要なデータを抽出するにはどうすればよいですか?

4

1 に答える 1

1

これにより、正しい軌道に乗ることができます。[ManyToMany] / 一般的なリストに遭遇した場合、同じメソッドへの再帰呼び出しを使用してそれを反映し、返された値を平坦化して一意のキーを形成するという考え方です。おそらく、問題に合わせて微調整する必要があります。以下のコードは、コレクション名、インデックス、およびプロパティ名から構築されたフォーマットされたキー文字列を含む辞書を返します。例えば:

Bars[0].Id = 1
Bars[1].Id = 2

コード:

//This is just a generic wrapper for the other Reflect method
private static Dictionary<string, string> Reflect<TModel>(TModel Model)
{
  return Reflect(Model.GetType(), Model);
}

private static Dictionary<string, string> Reflect(Type Type, object Object)
{
  var result = new Dictionary<string, string>();

  var properties = Type.GetProperties();

  foreach (var property in properties)
  {
    if (
      property.GetCustomAttributes(typeof(ManyToManyAttribute), true).Any() &&
      property.PropertyType.GetGenericTypeDefinition() == typeof(IList<>))
    {
      var genericType = property.PropertyType.GetGenericArguments().FirstOrDefault();
      var listValue = (IEnumerable)property.GetValue(Object, null);

      int i = 0;
      foreach (var value in listValue)
      {
        var childResult = Reflect(genericType, value);
        foreach (var kvp in childResult)
        {
          var collectionName = property.Name;
          var index = i;
          var childPropertyName = kvp.Key;
          var childPropertyValue = kvp.Value;

          var flattened = string.Format("{0}[{1}].{2}", collectionName, i, childPropertyName);
          result.Add(flattened, childPropertyValue);
        }

        i++;
      }
    }
    else
    {
      result.Add(property.Name, property.GetValue(Object, null).ToString());
    }
  }

  return result;

}
于 2013-11-05T03:06:14.837 に答える