2017-03-26 4 views
0

実行時にしかわからないデータセットから動的オブジェクトを作成して設定しようとしています。以下のコードでは、デザイン時にわからないいくつかの既知のフィールド(ID、プライマリデータ、DisplayOrder、IsActive)とユーザー定義フィールド(Phone Number)を持つ私のデータセットからIEnumerable結果を作成します。動的に構築される。以下のコードは動作しますが、ダイナミックフィールドの電話番号をハードコードしているためです。実行時に認識されたフィールドだけを処理するために、ラムダ式を動的に構築するにはどうすればよいですか。私は同等のものを求めています動的に作成されたラムダ式を使用して動的オブジェクトを作成して設定する方法

string fieldName = 'PhoneNumber = '; 
string fieldSource = 'pd.tbList_DataText'; 
string expression = 'pd=>new { ID = pd.ID, PrimaryData=pd.PrimaryData'; 
expression += fieldName; 
expression += FieldSource; 
expression += '.Where(ld => ld.DataRowID == pd.ID && ld.ListColumnID == 1).Select(ld => ld.DataField).DefaultIfEmpty("").First()})'; 

var results = primaryData.Select(expression); 

どうすればいいですか?ありがとう

  // Get base Data 
     IEnumerable<tbList_Data> primaryData = await _tbList_DataRepository.GetAsync(ld => ld.ListID == listId && (ld.IsActive  == includeInactive ? ld.IsActive : true)); 

     // Get Final Results 
     var results = primaryData.Select(pd => new { 
      Id = pd.ID, 
      PrimaryData = pd.PrimaryData, 
      PhoneNumber = pd.tbList_DataText.Where(ld => ld.DataRowID == pd.ID && ld.ListColumnID == 1).Select(ld => ld.DataField).DefaultIfEmpty("").First() 
     }); 
+0

iveはかなり長い間ダイナミックなプロパティを作成することに固執していましたが、私はこれまで可能だったことを試してみました。動的プロパティ部分への回答を楽しみにしています。 – Niklas

+0

あなたは方法を見つけたとしましょう、あなたは 'results'をどのように使うつもりですか?あなたがそれを知っていなくても、 'PhoneNumber'にどうやってアクセスしますか? – vyrp

+0

'System.Reflection' – Niklas

答えて

2

いくつかのオプションがあります。

1)タプル

var results = primaryData.Select(pd => new { 
    Id = pd.ID, 
    PrimaryData = pd.PrimaryData, 
    Extra = Tuple.Create("PhoneNumber", pd.tbList_DataText.Where(ld => ld.DataRowID == pd.ID && ld.ListColumnID == 1).Select(ld => ld.DataField).DefaultIfEmpty("").First()) 
}); 

// How to access: 
foreach (var result in results) 
{ 
    Console.WriteLine(result.Id); 
    Console.WriteLine(result.PrimaryData); 
    Console.WriteLine(result.Extra.Item1); 
    Console.WriteLine(result.Extra.Item2); 
} 

2)辞書

// Using C# 6 notation 
var results = primaryData.Select(pd => new Dictionary<string, object>{ 
    ["Id"] = pd.ID, 
    ["PrimaryData"] = pd.PrimaryData, 
    ["PhoneNumber"] = pd.tbList_DataText.Where(ld => ld.DataRowID == pd.ID && ld.ListColumnID == 1).Select(ld => ld.DataField).DefaultIfEmpty("").First() 
}); 

// Using C# 5 notation 
var results = primaryData.Select(pd => new Dictionary<string, object>{ 
    {"Id", pd.ID}, 
    {"PrimaryData", pd.PrimaryData}, 
    {"PhoneNumber", pd.tbList_DataText.Where(ld => ld.DataRowID == pd.ID && ld.ListColumnID == 1).Select(ld => ld.DataField).DefaultIfEmpty("").First()} 
}); 

// How to access: 
foreach(var result in results) 
{ 
    Console.WriteLine(result["Id"]); 
    Console.WriteLine(result["PrimaryData"]); 
    Console.WriteLine(result["PhoneNumber"]); 
} 

3)動的

var results = primaryData.Select(pd => { 
    dynamic result = new System.Dynamic.ExpandoObject(); 
    result.Id = pd.ID; 
    result.PrimaryData = pd.PrimaryData; 

    // Choose one of the following. Since you only "PhoneNumber" at runtime, probably the second one. 
    result.PhoneNumber = pd.tbList_DataText.Where(ld => ld.DataRowID == pd.ID && ld.ListColumnID == 1).Select(ld => ld.DataField).DefaultIfEmpty("").First(); 
    ((IDictionary<string, object>)result).Add("PhoneNumber", pd.tbList_DataText.Where(ld => ld.DataRowID == pd.ID && ld.ListColumnID == 1).Select(ld => ld.DataField).DefaultIfEmpty("").First()); 

    return result; 
}); 

// How to access: 
foreach(var result in results) 
{ 
    Console.WriteLine(result.Id); 
    Console.WriteLine(result.PrimaryData); 

    // Both work, independently how you created them 
    Console.WriteLine(result.PhoneNumber); 
    Console.WriteLine(((IDictionary<string, object>)result)["PhoneNumber"]); 
} 

EDIT:ちょうどREAフィールドソースも動的でなければならないという疑問が浮かび上がった。

Xldのタイプでなければなりません ​​3210

:だから、上記のコードでは、によってpb.tbList_DataTextのいずれかの発生を交換してください。しかし、気をつけて!このキャストは失敗する可能性があります。

また、フィールドの代わりにプロパティを使用する場合は、GetFieldの代わりにGetPropertyを使用します。

+0

素晴らしいです、ありがとうございます! – Mark

関連する問題