1

データベース クエリの結果を、C# コードで厳密に型指定されたオブジェクトにマップしようとしていました。そこで、データベースでクエリを実行し、リフレクションを使用してレコード列をオブジェクト プロパティにマップする SqlConnection クラスに、簡単で汚いヘルパー メソッドを作成しました。コードは以下のとおりです。

 public static T Query<T>(this SqlConnection conn, string query) where T : new()
    {
        T obj = default(T);

        using (SqlCommand command = new SqlCommand(query, conn))
        {
            using (SqlDataReader reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    obj = new T();

                    PropertyInfo[] propertyInfos;
                    propertyInfos = typeof(T).GetProperties();

                    for (int i = 0; i < reader.FieldCount; i++)
                    {
                        var name = reader.GetName(i);

                        foreach (var item in propertyInfos)
                        {
                            if (item.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase) && item.CanWrite)
                            {
                                item.SetValue(obj, reader[i], null);
                            }
                        }

                    }
                }
            }
        }

        return obj;
    }

  public class User
    {
        public int id { get; set; }
        public string firstname { get; set; }
        public string lastname { get; set; }
        public DateTime signupDate { get; set; }
        public int age { get; set; }
        public string gender { get; set; }
    }


   var user = conn.Query<User>("select id,firstname,lastname from users");      

上記のコードで改善できることがあれば、リフレクションを使用して値を結び付けるという上記のアプローチについて、セカンドオピニオンが欲しかっただけです。または、同じ結果を得るために取ることができる他のまったく異なるアプローチがある場合は?

propertyInfos のループを削除し、代わりに辞書を使用することで、おそらくヘルパー メソッドのコードを改善できると思います。他に微調整が必​​要なものはありますか?

PS: 私は Dapper を知っています。私は自分自身で似たようなものを実装して、より良い学習を支援したかっただけです。

4

2 に答える 2

2

あなたがやったことは、基本的にlinq-to-sqlや他のORマッパーが内部で行うことです。それがどのように機能するかの詳細を学ぶために、最初から何かを書くことは常に良い考えです。

より多くのインスピレーションが必要な場合、または本番環境ですぐに使用できるものが必要な場合は、linq-to-sqlを読むことをお勧めします。軽量でありながら有能です。

于 2011-10-22T09:22:36.533 に答える
0

私が考えることができることがいくつかあります:

  1. ループをスキップするには、次を使用できると思います。

    reader[item.Name]
    
  2. 私も似たようなことをしたことがありますが、ダッパーに遭遇したことはありません。リフレクションを使用しているかどうかはわかりませんが、スキルを磨くために他の人のコードを読むことは常に良い考えです (Scott Hanselman は頻繁にそうすることを勧めています)。

  3. また、こちらもご覧ください: http://www.codeproject.com/KB/database/metaquery_part1.aspx

  4. フィールドをデータベース列にマップする属性を実装できますが、それは単なる遊びです。

編集:

5: また、リーダーの while ループをスキップして最初の行だけを取得し、クエリが 1 つのオブジェクトのみを返すという事実を文書化することもできます。したがって、クエリが 1000 行を返す場合でも、1000 行をプルしません。

于 2011-10-22T09:35:38.027 に答える