2

私は次のように列挙可能です:

 IEnumerable<dynamic> collection = new 
 {  
    column1 = "1", column2 = "name", column3= "somevalue" 
 }, 
 new 
 { 
    column1 = "2",   column2 = "name2", column3= "somevalue2" 
 },
 new 
 { 
    column1 = "3", column2 = "name3", column3= "somevalue3" 
 }

など...動的タイプの列の数も変化する可能性があります。列の数は多かれ少なかれすることができます。

ここで、このIEnumerableコレクションでsomevalue2などを検索する場合は、列「column2」の行2(column1が常に主キーであると想定)にある次の情報が必要です。これは、この動的コレクションをデータ構造(.NETリスト/コレクション/ハッシュテーブルなど)に変換するための最良の方法であり、コレクションからの情報を照会するための最良の方法です。コレクションは最大で1ページのデータ(25行)になります。データを検索するための超高速で効率的な方法を実行するためのコードスニペットとデータ構造をいただければ幸いです。検索語が完全一致ではなく「含む」一致であると想定します。

4

3 に答える 3

4

これらは匿名型です。匿名型はコンパイラの機能であるため、レイアウトはコンパイル時に厳密に固定されるため、変更されることはありません。私はお勧めします:使用しないでくださいdynamic。例えば:

 var arr = new[] {
   new { column1 = "1", column2 = "name", column3= "somevalue" }, 
   new { column1 = "2", column2 = "name2", column3= "somevalue2" },
   new { column1 = "3", column2 = "name3", column3= "somevalue3" }
 };

これはすべて強く型付けされ、明確に定義されています。次のような通常の操作を使用できます。

var item2 = arr.FirstOrDefault(x => x.column1 == "2");

繰り返しますが、すべて静的型です。

すべての列を検索する場合は、辞書のようなものをお勧めします。

 var arr = new[] {
   new Dictionary<string,string> { {"column1", "1"}, ... }, 
   new Dictionary<string,string> { {"column1", "2"}, ... }, 
   new Dictionary<string,string> { {"column1", "3"}, ... }, 
 };

あなたはただ見ることができるので.Values.Contains(...)


編集:コメントで、私はそれをより明確に理解していると思います。実際には POCO 型 (動的型ではない)を返す不透明なメソッドを描いていますIEnumerable<dynamic>。一致する文字列メンバー (任意の名前) をチェックしたいと考えています。リフレクションでそれを行うことができるはずですが、FastMemberを使用するとはるかに高速になります。

static void Main()
{
    string search = "ame2";

    int rowIndex = 0;
    string[] names = null;
    TypeAccessor accessor = null;
    foreach(object row in GetData())
    {
        if(names == null)
        { // first row; get the property-names and build an accessor
            names = (from prop in row.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)
                     where prop.PropertyType == typeof (string)
                     select prop.Name).ToArray();
            accessor = TypeAccessor.Create(row.GetType());
        }

        foreach(var name in names)
        {
            var val = accessor[row, name] as string;
            if(val != null && val.Contains(search))
            {
                Console.WriteLine("row {0}, col {1}, val {2}", rowIndex, name, val);
            }
        }
        rowIndex++;
    }
}
static IEnumerable<dynamic> GetData()
{
    yield return new {column1 = "1", column2 = "name", column3 = "somevalue"};
    yield return new {column1 = "2", column2 = "name2", column3 = "somevalue2"};
    yield return new {column1 = "3", column2 = "name3", column3 = "somevalue3"};
}
于 2012-08-07T19:51:14.583 に答える
0

アイテムごとに異なる列を持つ動的オブジェクトにしたい場合は、次のように宣言できます。

IEnumerable<dynamic> collection = new dynamic[]
                                        {
                                            new  
                                                {
                                                    column1 = "1",
                                                    column2 = "name",
                                                    column3 = "somevalue"
                                                },
                                            new
                                                {
                                                    column1 = "2",
                                                    column2 = "name2"
                                                },
                                            new
                                                {
                                                    column1 = "3",
                                                    column2 = "name3",
                                                    column3 = "somevalue3",
                                                    column4 = "fourthValue"
                                                }
                                        };

それをリストに変換するのは簡単です:

// create a list
var list = new List<dynamic>(collection);

プロパティが存在しない可能性があるため、アイテムの検索はもう少し複雑です。

// find an item
var itemOne = collection.Where(i =>
                                    {
                                        try
                                        {
                                            if (i.column1 == "1")
                                            {
                                                return true;
                                            }
                                        }
                                        catch
                                        {
                                            // ignore error, column doesn't exist
                                        }
                                        return false;
                                    });
于 2012-08-07T19:54:09.120 に答える