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-mapper 在后台所做的。要了解它如何工作的细节,从头开始编写一些东西总是一个好主意。

如果您想要更多灵感或想要开箱即用的产品,我建议您阅读 linq-to-sql。它重量轻,但能胜任。

于 2011-10-22T09:22:36.533 回答
0

我能想到的有几点:

  1. 我认为为了跳过循环,您可以使用:

    reader[item.Name]
    
  2. 我自己也做过类似的事情,但我从来没有遇到过dapper。我不确定它是否使用反射,但阅读别人的代码以提高你的技能总是一个好主意(Scott Hanselman 经常建议这样做)。

  3. 你也可以看看: http: //www.codeproject.com/KB/database/metaquery_part1.aspx

  4. 您可以实现将字段映射到数据库列的属性,但这只是为了好玩。

编辑:

5:您也可以跳过读取器上的 while 循环,只取第一行,并记录您的查询仅返回一个对象的事实,因此如果查询返回一千行,它不会拉一千行。

于 2011-10-22T09:35:38.027 回答