1

这就是我(在工作中)学习创建类、使用 readRecord 方法创建数据库访问对象以从数据库中获取信息的方式。我很好奇,SF 社区对缩短它的建议是什么?我可以通过将 readRecord 代码向上移动到 DAO 方法中并在其中更改它来摆脱几行代码,但这仍然存在可能有数百行代码的问题......仅用于类,并用于在 DAO 中获取这些属性的值。

我知道在课堂上没有什么可做的(我的意思是,你不能只自动生成一堆属性......Visual Studio 不知道我要做什么!),但是对于 DAO ,有没有办法遍历类中的所有属性,确定它们的类型,然后获取信息?我讨厌输入数百个“property = dr.GetVariableType("variablename");” 一遍又一遍地!

抱歉代码长度...我复制了 6 次属性以了解我在说什么。

班级

namespace MySoftware
{
    public class User
    {
            public int userId { get; set; }
            public string userName { get; set; }
            public string firstName { get; set; }
            public string lastName { get; set; }
            public string MI { get; set; }
            public string suffix { get; set; }
            public string email { get; set; }
            public string phone{ get; set; }
            public string SSN { get; set; }
            public int roleId { get; set; }
            public bool IsTemp { get; set; }
            public int userId { get; set; }
            public string userName { get; set; }
            public string firstName { get; set; }
            public string lastName { get; set; }
            public string MI { get; set; }
            public string suffix { get; set; }
            public string email { get; set; }
            public string phone{ get; set; }
            public string SSN { get; set; }
            public int roleId { get; set; }
            public bool IsTemp { get; set; }
            public int userId { get; set; }
            public string userName { get; set; }
            public string firstName { get; set; }
            public string lastName { get; set; }
            public string MI { get; set; }
            public string suffix { get; set; }
            public string email { get; set; }
            public string phone{ get; set; }
            public string SSN { get; set; }
            public int roleId { get; set; }
            public bool IsTemp { get; set; }
            public int userId { get; set; }
            public string userName { get; set; }
            public string firstName { get; set; }
            public string lastName { get; set; }
            public string MI { get; set; }
            public string suffix { get; set; }
            public string email { get; set; }
            public string phone{ get; set; }
            public string SSN { get; set; }
            public int roleId { get; set; }
            public bool IsTemp { get; set; }
            public int userId { get; set; }
            public string userName { get; set; }
            public string firstName { get; set; }
            public string lastName { get; set; }
            public string MI { get; set; }
            public string suffix { get; set; }
            public string email { get; set; }
            public string phone{ get; set; }
            public string SSN { get; set; }
            public int roleId { get; set; }
            public bool IsTemp { get; set; }
            public int userId { get; set; }
            public string userName { get; set; }
            public string firstName { get; set; }
            public string lastName { get; set; }
            public string MI { get; set; }
            public string suffix { get; set; }
            public string email { get; set; }
            public string phone{ get; set; }
            public string SSN { get; set; }
            public int roleId { get; set; }
            public bool IsTemp { get; set; }
    }
}

namespace MySoftware
{
        public static List<User> GetUsers(int departmentId)
        {
            List<User> user = new List<User>();

            try
            {
                using (SqlConnection conn = ConnectionHelper.GetConnection("connectionString"))
                {
                    SqlCommand cmd = new SqlCommand("GetUsers", conn);
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@DeptId", departmentId);
                    using (SqlDataReader dr = cmd.ExecuteReader())
                    {
                        while (dr.Read())
                        {
                            users.Add(readUserRecord(dr));
                        }
                    }

                    return users;
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Failed to get users", ex);
            }
        }
    }

然后我阅读了记录(这通常位于 DAO 的底部。

    public static User ReadRegRecord(SqlDataReader dr)
    { 
        User user = new User();

        user.userId = dr.GetInt32("Id");
        user.userName = dr.GetString("UserName");
        user.schoolId = dr.GetInt32("schoolId");
        user.roleId = dr.GetInt32("roleId");
        user.Active = dr.GetBoolean("Active");
        user.IsTemp = dr.GetBoolean("IsTemp ");
        user.firstName = dr.GetString("firstName");
        user.MI = dr.GetString("MI");
        user.lastName = dr.GetString("lastName");
        user.suffix = dr.GetString("Suffix");
        user.email = dr.GetString("email");
        user.Phone = dr.GetString("Phone ");
        user.SSN = dr.GetString("SSN");
        user.userId = dr.GetInt32("Id");
        user.userName = dr.GetString("UserName");
        user.schoolId = dr.GetInt32("schoolId");
        user.roleId = dr.GetInt32("roleId");
        user.Active = dr.GetBoolean("Active");
        user.IsTemp = dr.GetBoolean("IsTemp ");
        user.firstName = dr.GetString("firstName");
        user.MI = dr.GetString("MI");
        user.lastName = dr.GetString("lastName");
        user.suffix = dr.GetString("Suffix");
        user.email = dr.GetString("email");
        user.Phone = dr.GetString("Phone ");
        user.SSN = dr.GetString("SSN");
        user.userId = dr.GetInt32("Id");
        user.userName = dr.GetString("UserName");
        user.schoolId = dr.GetInt32("schoolId");
        user.roleId = dr.GetInt32("roleId");
        user.Active = dr.GetBoolean("Active");
        user.IsTemp = dr.GetBoolean("IsTemp ");
        user.firstName = dr.GetString("firstName");
        user.MI = dr.GetString("MI");
        user.lastName = dr.GetString("lastName");
        user.suffix = dr.GetString("Suffix");
        user.email = dr.GetString("email");
        user.Phone = dr.GetString("Phone ");
        user.SSN = dr.GetString("SSN");
        user.userId = dr.GetInt32("Id");
        user.userName = dr.GetString("UserName");
        user.schoolId = dr.GetInt32("schoolId");
        user.roleId = dr.GetInt32("roleId");
        user.Active = dr.GetBoolean("Active");
        user.IsTemp = dr.GetBoolean("IsTemp ");
        user.firstName = dr.GetString("firstName");
        user.MI = dr.GetString("MI");
        user.lastName = dr.GetString("lastName");
        user.suffix = dr.GetString("Suffix");
        user.email = dr.GetString("email");
        user.Phone = dr.GetString("Phone ");
        user.SSN = dr.GetString("SSN");
        user.userId = dr.GetInt32("Id");
        user.userName = dr.GetString("UserName");
        user.schoolId = dr.GetInt32("schoolId");
        user.roleId = dr.GetInt32("roleId");
        user.Active = dr.GetBoolean("Active");
        user.IsTemp = dr.GetBoolean("IsTemp ");
        user.firstName = dr.GetString("firstName");
        user.MI = dr.GetString("MI");
        user.lastName = dr.GetString("lastName");
        user.suffix = dr.GetString("Suffix");
        user.email = dr.GetString("email");
        user.Phone = dr.GetString("Phone ");
        user.SSN = dr.GetString("SSN");
        user.userId = dr.GetInt32("Id");
        user.userName = dr.GetString("UserName");
        user.schoolId = dr.GetInt32("schoolId");
        user.roleId = dr.GetInt32("roleId");
        user.Active = dr.GetBoolean("Active");
        user.IsTemp = dr.GetBoolean("IsTemp ");
        user.firstName = dr.GetString("firstName");
        user.MI = dr.GetString("MI");
        user.lastName = dr.GetString("lastName");
        user.suffix = dr.GetString("Suffix");
        user.email = dr.GetString("email");
        user.Phone = dr.GetString("Phone ");
        user.SSN = dr.GetString("SSN");
        return user;
    }
}

例如,有没有办法为 DAO/readRecord 做这样的事情?(我知道这不起作用,但如果有人能想到类似的东西,我很想听听)。

        foreach (var prop in student.GetType().GetProperties())
        {
            if (prop.PropertyType == "String")
            {
                prop.Value = dr.GetString(prop.Name.ToString());
            }
            if (prop.PropertyType == "Int")
            {
                prop.Value = dr.GetInt32(prop.Name.ToString());
            }
        }
4

4 回答 4

1

您应该查看 ORM,例如Entity FrameworkNHibernate

如果出于某种原因这些不适合您的需求,我建议您考虑编写T4 模板,以便您可以生成所需的确切数据访问代码。T4 是 Visual Studio 中一个非常强大但未被充分利用的工具。

于 2013-10-21T21:27:53.817 回答
0

这是一个典型的模式:

  1. 使用 EF 生成映射到现有数据库表的类
  2. 使用 Automapper 自动映射具有相同名称的属性和/或应用自定义映射逻辑,例如规范化

这为您节省了将 DataReader 列映射到实体属性的繁琐代码。

于 2013-10-21T21:21:02.197 回答
0

它的样子对我来说似乎很好。当然有人可能会争辩说,有一些工具可以从你那里抽象出这项工作,但既然你想做,我就会这样做。

如果您想要一些可以减轻您负担的东西,您可以使用DapperDotNet或 NHibernate/EF 来获得更臃肿的解决方案。

使用 Dapper,您的 DAO 将如下所示:


public static List GetUsers(int departmentId)
{
    try
    {
        using (SqlConnection conn = ConnectionHelper.GetConnection("connectionString"))
        {
            return conn.Query("GetUsers", new { DeptId = departmentId }).ToList();            
        }
    }
    catch (Exception ex)
    {
        throw new Exception("Failed to get users", ex);
    }
}
于 2013-10-21T21:22:44.223 回答
0

试试这个(在我的脑海中):

foreach (var prop in typeof(User).GetProperties())
{
    prop.SetValue(student, dr[prop.Name]);
}

假设所有属性的名称对应于数据读取器中的名称,并且来自数据读取器的任何值都可以强制转换为相应的属性(这是使用 ORM 的一个很好的理由,正如其他人在答案和评论)。

您可能还需要检查DBNull值。由于SqlDataReader'sIsDBNull方法只采用列索引的整数,而不是列名,因此您必须使用GetOrdinal找出与每个名称对应的列位置:

foreach (var prop in typeof(User).GetProperties())
{
    object val;
    if (dr.IsDBNull(dr.GetOrdinal(prop.Name))) {
        val = null;
    } else {
        val = dr[prop.Name];
    }
    prop.SetValue(student, val);
}
于 2013-10-21T22:05:02.620 回答