2011-07-19 18 views
-1

質問:私はMyConvertDataRowToEntity(DataRow行) を持っていて、親と内部のTオブジェクトを呼び出すときに、despendタイプの子と同じ関数を呼び出す必要があります私はDataRowパラメータを渡しますか? MakeGenericMethodの呼び出し時に問題が発生します。 型をDataSet、stringおよびString型に変更しました。 運がありません。 は(私は子供たちが列名でBU接頭辞オブジェクト認識 - PrefixDataColumn)をDataRowパラメーター - MakeGenericMethodで再帰呼び出しが失敗する

public static T MyConvertDataRowToEntity<T>(DataRow row) where T : class, new() 
    { 

     Type objType = typeof(T); 
     Type parentObjType = typeof(T); 
     T obj = Activator.CreateInstance<T>(); //hence the new() contsraint 
     PropertyInfo propertyGenericType = null; 
     object childInstance = null; 
     PropertyInfo property; 
     string childColumnName = string.Empty ; 
     foreach (DataColumn column in row.Table.Columns) 
     { 
      column.ColumnName = column.ColumnName.Replace("_", ""); 

      string PrefixDataColumn; 
      if (column.ColumnName.IndexOf(".") > (-1)) 
      { 
       ///gets the prefix that is the same as child entity name 
       PrefixDataColumn = column.ColumnName.Substring(0, column.ColumnName.IndexOf(".")); 
       ///the column name in the child 
       int length = column.ColumnName.Length - 1; 
       int start = column.ColumnName.IndexOf(".") + 1; 
       childColumnName = column.ColumnName.Substring(column.ColumnName.IndexOf(".") + 1); 
       propertyGenericType = objType.GetProperty(PrefixDataColumn, 
            BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.FlattenHierarchy); 
       parentObjType = objType; 
       if (propertyGenericType != null) 
       { 
        Type childType = propertyGenericType.PropertyType; 
        objType = childType; 
        childInstance = Activator.CreateInstance(propertyGenericType.PropertyType); 


        // get the get method for the property 
        MethodInfo method = propertyGenericType.GetGetMethod(true); 
        // get the generic get-method generator 
        MethodInfo genericHelper = typeof(DataUtil).GetMethod("MyConvertDataRowToEntity", BindingFlags.Public | BindingFlags.Static); 

        List<Type> signature = new List<Type>(); 
        // first type parameter is type of target object 
        signature.Add(childType); 

        //next parameters are real types of method arguments 
        foreach (ParameterInfo pi in genericHelper.GetParameters()) 
        { 
         signature.Add(pi.ParameterType); 
        } 

        // last parameters are known types of method arguments 
        signature.AddRange(typeof(T).GetGenericArguments()); 

        // reflection call to the generic get-method generator to generate the type arguments 
        //MethodInfo constructedHelper = genericHelper.MakeGenericMethod(signature.ToArray()); 

        // reflection call to the generic get-method generator to generate the type arguments 
        MethodInfo constructedHelper = genericHelper.MakeGenericMethod(childType); 

        // now call it. The null argument is because it's a static method. 
        object ret = constructedHelper.Invoke(null, new object[] { method }); 

        // object myObj = method.Invoke(null, row); 
        //// property.SetValue(obj, MyConvertDataRowToEntity<childInstance>(DataRow row),null); 
        // childInstance = DataUtil.GetMethod("MyConvertDataRowToEntity").MakeGenericMethod(childType); //MyConvertDataRowToEntity<object>(row); 

        //childType initializedChild = ; 
        //property.SetValue(obj, value, null); 
        //objType = parentObjType; 
       } 
       else 
       { 
        continue; 
       } 
      } 


     } 
     return obj; 
    } 

このエラーを取得する:タイプの オブジェクトのSystem.Reflection.RuntimeMethodInfo "型に変換することができません「System.Data.DataRow」。

解決方法はありますか?

p.s. できるだけコードを絞り込みました。

どのようにして、desedant型で再帰的にメソッドを呼び出し、datarowを渡すことができますか?

+1

長いコードをチェックするデバッガがありません。問題のある領域に絞り込んでください。いくつかのテキストがあなたが達成しようとしているものに役立ちます。 –

+1

問題を実証する短くて完全なプログラムが本当に役に立ちます。私はMyConvertDataRowToEntity (DataRowの行) を持っていると私はタイプの親からのオブジェクトを呼び出すと私はdespend型の子供と同じ関数を呼び出す方法についてはhttp://tinyurl.com/so-hints –

+0

をお読みください私はDataRowパラメータを渡す必要がありますか? MakeGenericMethodの呼び出し時に問題が発生します。 型をDataSet、stringおよびString型に変更しました。 運がありません。 –

答えて

1

MyConvertDataRowToEntity<ChildType>を呼び出していますが、これらのフィールドのみを含むデータ行ではなく、プロパティとしてgetaccessor methodinfoをパラメータとして渡すためです。

現在使用しているコード処理ロジックを継続したい場合は、カラム名の先頭から削除したいフィールド( "。")を含む新しいデータローを作成する必要があります。

また、受け入れられた列名であるソースオブジェクトのヘルパーメソッドを作成し、単純に値を更新することもできます。

static void UpdateItemProperty<T>(T item, string columnName, object rowValue) { 
    var prefixColumn=columnName.IndexOf(".")==-1 ? columnName : columnName.Split(".")[0]; 
    var pi = typeof(T).GetProperty(prefixColumn // Add your binding flags); 
    // if pi==null then there is an error... 
    if (column.ColumnName.IndexOf(".") == (-1)) { // No Nesting 
    pi.SetValue(item,rowValue); 
    return; 
    } 
    // Nesting 
    var child=pi.GetValue(item); 
    if (child==null) { 
     // Logic here to get childs type and create an instance then call pi.SetValue with child 
    } 
    var remainder=string.Join(',',columnName.Split(".").Skip(1).ToArray()); 
    // make your generic method info for UpdateItemProperty with pi.PropertyType into mi 
    mi.Invoke(null,new object[] { child,remainder,value }; 
} 
+0

お返事ありがとうございます。問題はデータの変更ではなく、パラメータの送信です。私はchildTypeでメソッドを呼び出すと、私は行を送信できないことを意味します。それは失敗します: "'' System.Reflection.RuntimeMethodInfo 'は、' System.Data.DataRow 'の型に変換できません。"それはトラブルです! –

+0

私の応答の全体的なポイントは、あなたの呼び出しの行が、メソッドとして必要なデータローではなく、プロパティとしてメソッドの情報をパラメータとして渡していることです。戻り値を取得するには、まずgetmethodを呼び出す必要がありますか? –

+0

こんにちは!たぶん私は私の問題ではっきりしていなかったでしょう。私は子供を持つ階層的なオブジェクトを持っています。厳密に型指定されたオブジェクトの一部のプロパティを満たすと、そのプロパティでMyConvertDataRowToEntityを再帰的に実行したいと考えています。私は関連する列のデータロー作成だけを試してみて、あなたに戻ってきます。あなたの助けをたくさんありがとう! –

関連する問題