列表正在复制同一行

本文关键字:一行 复制 列表 | 更新日期: 2023-09-27 18:31:07

我正在尝试从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();
        }
    }

列表正在复制同一行

您需要

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

while (reader.Read())
{
    var customer = new Customer();
    // As before...

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

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

试试这个:

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

我更喜欢下面这样。

考虑。。。

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

SqlConnectionSqlCommandSqlDataReader实现IDisposable

using更简单且等效时,为什么要使用try-finally

为什么不使用对象初始值设定项?

当您只需要 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();