如何从SQL数据库填充C#中的通用对象列表

时间:2010-03-16 18:29:03

标签: c# asp.net sql-server

我正在学习ASP.NET c#并尝试将最佳实践融入我的应用程序中。我读到的所有内容都表示基于关注点的分离将我的应用程序分层为DAL,BLL,UI等。我没有传递数据表,而是考虑使用自定义对象,这样我就可以松散地耦合到我的数据层,并且可以利用VS中的intellisense。我假设这些对象会被视为DTO?

首先,这些对象在我的图层中的位置? BLL,DAL,其他?

其次,当从SQL填充时,我应该循环访问数据读取器以填充列表还是首先填充数据表,然后循环遍历表以填充列表?我知道你应该尽快关闭数据库连接,但是填充数据表然后循环遍历列表似乎需要更多的开销。

第三,我现在看到的一切都说使用Linq2SQL。我打算学习Linq2SQL,但此时我正在使用没有外键设置的遗留数据库,我没有能力修复它。另外,在开始进入像nHibernate这样的ORM解决方案之前,我想了解更多关于c#的知识。同时我不想为每个查询键入所有连接和SQL管道。现在可以使用Enterprise DAAB吗?

2 个答案:

答案 0 :(得分:17)

你在一个问题上有很多问题。

Linq2SQL只是一种ORM类型,如果你要走那条路,我会看一下实体框架(微软的orm)。

让我们先谈谈分层应用程序,以帮助您了解如何填充对象。 您的典型数据库应用程序由3个层组成(有些人说4个并且将数据库本身称为一个层,它确实无关紧要)。您有以下内容:

  • UI
  • BLL
  • DAL

因此,您的沟通是与BLL进行的UI会谈以及BLL与DAL的对话。 DAL将一些数据返回给BLL,BLL又将其呈现给UI。我不知道谁告诉你数据集/表格不好......确保读者更快但并不意味着使用数据表是不好的。

让我举个例子。不要把你的DAL想象成一个简单的类。开始将DAL层视为不同类的整个文件夹。其中一个类是静态DB类。它是静态的,因为您正在处理一个数据库(在大多数情况下),因此无需实例化该类。所以它可能看起来像这样:

public static class DB {
private static readonly string connectionString = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;
private static readonly DbProviderFactory factory = DbProviderFactories.GetFactory(dataProvider);

public static int Update(string sql)
        {
            using (DbConnection connection = factory.CreateConnection())
            {
                connection.ConnectionString = connectionString;

                using (DbCommand command = factory.CreateCommand())
                {
                    command.Connection = connection;
                    command.CommandText = sql;

                    connection.Open();
                    return command.ExecuteNonQuery();
                }
            }
        }

public static DataTable GetDataTable(string sql)
        {
            using (DbConnection connection = factory.CreateConnection())
            {
                connection.ConnectionString = connectionString;

                using (DbCommand command = factory.CreateCommand())
                {
                    command.Connection = connection;
                    command.CommandType = CommandType.Text;
                    command.CommandText = sql;

                    using (DbDataAdapter adapter = factory.CreateDataAdapter())
                    {
                        adapter.SelectCommand = command;

                        DataTable dt = new DataTable();
                        adapter.Fill(dt);

                        return dt;
                    }
                }
            }
}

其中一些来自dofactory网站。学习如何使用设计模式的重要资源。无论如何这只是一个.class文件。现在您需要另一个来说客户端(客户数据访问对象)。

好的,你怎么能使用你创建的数据库类(我会使用sprocs的组合但是为了使这个简单的帖子让我们现在避免使用存储过程)。如果我需要获得客户,我可以定义:

public IList<Customer> GetCustomers()
{
    StringBuilder sql = new StringBuilder();
    sql.Append(" SELECT CustomerId, CompanyName, City, Country ");
    sql.Append("   FROM Customer ");

    DataTable dt = Db.GetDataTable(sql.ToString());

    return MakeCustomers(dt);
}

请记住,这是一个完全不同的.class文件。好吧,如何让客户看起来:

private IList<Customer> MakeCustomers(DataTable dt)
        {
            IList<Customer> list = new List<Customer>();
            foreach (DataRow row in dt.Rows)
                list.Add(MakeCustomer(row));

            return list;
        }

所以我在这里做的是我有一个充满客户的数据表。我需要循环遍历数据表的每一行并使客户:

private Customer MakeCustomer(DataRow row)
        {
            int customerId = int.Parse(row["CustomerId"].ToString());
            string company = row["CompanyName"].ToString();
            string city = row["City"].ToString();
            string country = row["Country"].ToString();

            return new Customer(customerId, company, city, country);
        }

因此,该客户是新客户并存储在客户列表中。

这只是您的数据访问层所做的一个小例子。数据库类只存储连接字符串和函数以获取数据集或获取数据表,甚至在您的情况下获取数据读取器(您也可以这样做)。 CustomerDAO类只是一个处理客户对象的类,可以实现一个ICustomer接口。

那么Customer类本身在哪里?它可以在另一个文件夹中作为业务层,因为它只是一个业务对象。您可以在此处设置客户类内的验证和必填字段。

您的用户界面根本没有与数据对象,数据集或SQL相关的任何内容。您的业​​务层也与它无关(它定义了业务对象背后的一些规则)。您的dal可以非常灵活(可以使用SQL,Oracle等),或者可以限制为说SQL Server,如果这是您计划执行的操作。不要过度使用你的应用程序。如果您是MS人并且肯定只使用SQL Server,那么尝试推出适用于任何供应商的最终DAL,不会让您的工作变得困难。可以使用SQLCommand,SQLConnection等

答案 1 :(得分:0)

去看看Telerik的OpenAccess ORM。您不必将其用作“ORM”,但它可以让您快速为表生成类,而无需全部输入。然后,您可以在DAL中使用这些强类型类,无论它是自定义编写还是基于ORM的其他内容。在这种情况下,您只是将它用于代码生成,以便快速入门(这些对象非常简单 - 也就是说,如果您要手写它们,那么就是您要开始的地方)。

至于从其他对象中抽象DAL对象,请查看WCF。您可以将它放在每个图层(UI / Biz / DAL)之间,它将生成代理对象,以处理您关注点的分离。