C # Database Mapper

c# dapper orm

Question

Je cherchais à mapper les résultats de mes requêtes de base de données pour taper fortement des objets dans mon code c #. J'ai donc écrit une méthode d'assistance rapide et sale sur la classe SqlConnection qui exécute la requête sur la base de données et utilise la réflexion pour mapper les colonnes d'enregistrement aux propriétés de l'objet. Le code est ci-dessous:

 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");      

Je voulais juste un deuxième avis sur mon approche ci-dessus consistant à utiliser la réflexion pour lier les valeurs ensemble, s'il y a quelque chose que je peux faire mieux dans le code ci-dessus. Ou s'il y a une autre approche totalement différente que je peux prendre pour obtenir le même résultat?

Je pense que je peux probablement améliorer le code dans la méthode d'assistance en supprimant la boucle pour propertyInfos et en utilisant un dictionnaire à la place. Y a-t-il autre chose à modifier?

PS: je suis au courant de Dapper, je voulais juste mettre en œuvre quelque chose de similaire pour m'aider à mieux apprendre.

Réponse acceptée

Ce que vous avez fait est fondamentalement ce que font linq-to-sql ou d'autres mappeurs d'OR-sous le capot. Pour apprendre comment cela fonctionne, il est toujours bon d’écrire quelque chose à partir de zéro.

Si vous voulez plus d'inspiration ou si vous voulez avoir quelque chose qui soit prêt pour une utilisation en production, nous vous recommandons de lire linq-to-sql. Il est léger, mais compétent.


Réponse populaire

Il y a quelques choses auxquelles je peux penser:

  1. Je pense que pour sauter la boucle, vous pouvez utiliser:

    reader[item.Name]
    
  2. J'ai fait quelque chose de similaire moi-même, mais je n'ai jamais rencontré Dapper. Je ne suis pas sûr que cela utilise la réflexion, mais c'est toujours une bonne idée de lire le code de quelqu'un d'autre pour aiguiser vos compétences (Scott Hanselman recommande souvent de le faire).

  3. Vous pouvez également consulter: http://www.codeproject.com/KB/database/metaquery_part1.aspx

  4. Vous pouvez implémenter un attribut qui mappe un champ à une colonne de base de données, mais c'est juste pour le fun.

Modifier:

5: Vous pouvez également ignorer la boucle while sur le lecteur et prendre la première ligne, et documenter le fait que votre requête ne retourne qu'un seul objet.




Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi