3

我正在尝试从 SQL Server 检索客户列表,问题是,该列表仅返回同一行的副本。我考虑过可能在我的数据阅读器中添加一个 foreach 循环,但我不确定如何实现它。任何帮助表示赞赏。

public IList<Customer> GetCustomers()
    {
        IList<Customer> customers = new List<Customer>();

        var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["conn"].ConnectionString);
        conn.Open();
        try
        {
            var command = new SqlCommand
            {
                CommandText = "SELECT * FROM customer",
                Connection = conn
            };
            SqlDataReader reader = command.ExecuteReader();
            var customer = new Customer();
            while (reader.Read())
            {
                customer.CustId = (int) reader["cust_id"];
                customer.CustCode = (string) reader["cust_code"];
                customer.CustName = (string) reader["cust_name"];
                customer.CustDescr = (string) reader["cust_descr"];
                customer.CreatedDt = (DateTime) reader["created_dt"];
                customers.Add(customer);
            }
            return customers;
        }
        finally
        {
            conn.Close();
            conn.Dispose();
        }
    }
4

4 回答 4

8

您需要var customer = new Customer();进入while循环(否则,您只会创建一个 的实例Customer,反复覆盖其属性,并将同一个实例多次添加到列表中):

while (reader.Read())
{
    var customer = new Customer();
    // As before...
于 2013-09-11T16:23:22.593 回答
4

您看到副本的原因是因为您不断将对同一Customer实例的引用添加到集合中。当您更新while循环中的对象时, 中的每个引用List也会更新。

相反,您应该在循环的每次迭代中创建一个新实例。

于 2013-09-11T16:25:06.220 回答
3

尝试这个:

        while (reader.Read())
        {
          var customer = new Customer();
            customer.CustId = (int) reader["cust_id"];
            customer.CustCode = (string) reader["cust_code"];
            customer.CustName = (string) reader["cust_name"];
            customer.CustDescr = (string) reader["cust_descr"];
            customer.CreatedDt = (DateTime) reader["created_dt"];
            customers.Add(customer);
        }
于 2013-09-11T16:24:21.427 回答
0

我更喜欢它,如下所示。

考虑 ...

当您可能并不总是想要时,为什么要建立一个列表?

SqlConnectionSqlCommandSqlDataReader实施IDisposable

为什么使用try-finallywhenusing更简单且等效?

为什么不使用对象初始化器?

当您只需要 5 列时,为什么要返回所有列?

除非必须,否则不要打开连接。


public IEnumerable<Customer> GetCustomers()
{
    using (var connection = new SqlConnection(
        ConfigurationManager.ConnectionStrings["conn"].ConnectionString));
    {
        using (var command = new SqlCommand
                {
                    CommandText = 
                        "SELECT " +
                            "cust_id, " +
                            "cust_code, " +
                            "cust_name, " +
                            "cust_descr, " +
                            "created_dt " +
                            " FROM customer",
                    Connection = connection
                })
        {
            connection.Open();
            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    yield return new Customer
                    {
                        CustId = reader.GetInt32(0),
                        CustCode = reader.GetString(1),
                        CustName = reader.GetString(2),
                        CustDescr = reader.GetString(3),
                        CreatedDt = reader.GetDateTime(4)
                    };
                }
            }
        }
    }
}

那么,如果你需要一份清单

var customers =  GetCustomers().ToList();
于 2013-09-11T16:38:27.690 回答