DataTable Wrapper或如何将UI与业务逻辑分离

时间:2009-03-26 18:13:04

标签: asp.net gridview webforms datatable decoupling

我正在使用网络表单,C#,Asp.net。 众所周知,在这个模型中,UI和业务逻辑经常混合在一起。如何有效地分离这些?

我想使用的例子是: 我有一个GridView和一个DataTable(GridView绑定到DataTable,DataTable来自存储过程)。

我希望将GridView(UI)和DataTable(业务逻辑)分离。

为DataTable编写包装器是否值得?是否有经过验证和测试的实用模式,您可以建议遵循这些模式?

如果有经验的人可以发光,那就太棒了。 而且,作为最后一点,我想说ASP MVC现在不是一个选项,所以不推荐它。

我的数据库访问层返回一个DataTable。 请注意,我必须使用此数据库层,因为这是公司政策。

3 个答案:

答案 0 :(得分:2)

我最近经历过这个问题,同时从我们的UI层解耦了很多相同的东西。

您可以看到我的进度herehere

在我看来,DataTable 代表业务逻辑。具体来说,它的数据直接从数据库中提取。业务逻辑将数据转换为真正有用的业务对象。

然后,第一步是将DataTable与Business对象分离。

您可以通过创建构成DataTables的DataTables和Collections的对象和List<object>,然后创建一个显示这些对象的ListView。我在上面发布的链接中介绍了后面的步骤。前面的步骤就像下面这样简单:

  1. 创建一个代表您的对象的类。
  2. 遍历您的DataTable(或DataSet,或者您检索数据)并将这些字段推送到该对象的属性(或List<T>);
  3. 将List返回到Gridview或ListView进行显示。
  4. 这样,ListView或Gridview就不会与您检索数据的方法紧密耦合。如果您决定稍后从JSON查询或XML文件获取数据会发生什么?然后你必须把它建在那里。

    第1步 - 从数据库获取数据

    有多种方法可以从数据库中获取数据,我无法在这里查看所有数据。我假设您已经知道如何从数据库中检索数据,如果不这样做,则需要quite a few links。让我们假装您已连接到数据库,并使用SQLDataReader来检索数据。我们会去那里。

    类图

    Foo
    ----
    id
    Name
    Description
    

    这是方法:

     private void FillDefault(SqlDataReader reader, Foos foo)
            {
                try
                {
                    foo.id = Convert.ToInt32(reader[Foo.Properties.ID]);
                    foo.Name = reader[Foo.Properties.NAME].ToString();
    
    
                 if (!string.IsNullOrEmpty(
                    reader[Foo.Properties.DESCRIPTION].ToString()))
                     foo.Description = 
                     reader[Foo.Properties.DESCRIPTION].ToString();
                 else foo.Description = string.Empty;
                }
                catch (Exception ex)
                {
                   throw new Exception(
                   string.Format("Invalid Query. 
                   Column '{0}' does not exist in SqlDataReader.", 
                   ex.Message));
                }
            }
    

    一旦发生这种情况,您可以在针对while函数的SQLDataReader.Read()循环中完成该过程,从而返回一个列表。

    一旦你这样做,让我们假装你返回的Foo是一个列表。如果您这样做,并按照我上面给出的第一个链接,您可以将Dictionary<TKey, TValue>替换为List<T>并获得相同的结果(略有不同)。 Properties类只包含数据库中的列名,因此您可以在一个地方更改它们(如果您想知道的话)。

    DataTable - 基于评论更新

    您始终可以插入中间对象。在这个例子中,我在DataTable和UI之间插入了一个Business Layer,我已经讨论了我上面要做的事情。但是DataTable不是业务对象;它是数据库的直观表示。您无法将其传输到UI层并将其称为解耦。他们说你必须使用DataTable,他们是否说将DataTable传输到UI?我无法想象他们会这样。如果你这样做,那么你永远不会被解耦。在DataTable和UI层之间总是需要一个中间对象。

答案 1 :(得分:0)

我首先将数据表解耦到垃圾桶。构建一个域层,然后构建一个处理数据库的数据访问层(建议使用ORM)。

然后构建一个服务层,为UI提供数据。所有业务逻辑都应该在服务或实体内部。

答案 2 :(得分:0)

考虑实施MVP(模型视图展示器)模式。它通过演示者界面为您提供商业逻辑的分离,这也允许更好的单元测试功能。然后,aspx页面的代码隐藏只是事件的连接器和属性的getter / setter。您可以在MS模式和实践企业应用程序块中找到它(CAB - 复合应用程序块 - 如果我没有误会)。
您可以在此处详细了解:http://msdn.microsoft.com/en-us/magazine/cc188690.aspx
但是从DataTable / DataSets到对象(PO​​CO)也是首选。