从另一个类绑定转发器控件



我正在开发一个应用程序,该应用程序使用数据库查询来使用中继器控制显示数据。

我的中继器控件放在我的页面"show.aspx"上,我有另一个类,在那里我有数据绑定的方法。

那么,从我的数据类绑定中继器的最佳方法是什么呢?

此外,我还为中继器做了一个扩展方法,称为BindTable();对我来说,只需在"show.cs"类中调用这个方法就可以很容易地绑定数据(我指的是表单加载)。该方法以sql查询为参数,一切都由扩展方法在后台完成。

rptDisplay.BindTable("select * from table");

但我正在寻找更好的方法。我不能从我所有数据绑定方法所在的数据类访问中继器吗?

根据您的评论,您的目标是从表单中考虑出执行数据绑定的代码,以保持表单代码的整洁。这很好,因为检索和绑定数据的代码可能是代码隐藏文件的重要组成部分
首先,我认为像您已经做的那样创建一个扩展方法是一种非常好且优雅的方法。它适用于页面上的多个中继器和不同的SQL语句。那么,如何进一步改进呢

现在,您可以在代码后面直接向扩展方法提供SQL语句。这是可行的,但为了真正清晰地分离关注点,我不建议将语句直接包含在UI代码中,因为这是它使用SQL进行数据访问的细节。如果您决定在以后的某个时间点引入一个提供数据的服务层,则必须对UI代码进行大量更改。这取决于你来决定在你的背景下这是否是一个值得努力的现实场景
步骤如下:

  1. 创建包含与UI相关的数据的数据传输对象(DTO)
  2. 创建数据访问类(也称为存储库类),这些类不返回DataTables/Sets,而是使用GetById、GetAll、GetByName等方法返回集合或单个DTO,这些方法描述了对数据库的相关查询。MicroORM(例如Dapper.NET)可以在从数据库对象(DataTables、DataReaders)到DTO的(无聊的)映射过程中为您提供支持。还包括更新数据库的方法
  3. 在表单中,通过调用存储库来检索数据,并将中继器绑定到DTO集合

引入这些更改后,您会注意到不是数据绑定代码使代码隐藏文件增长,而是数据访问代码。一旦将此代码移动到存储库,数据绑定就只设置DataSource属性和对DataBind()的调用。所以你的扩展方法会很小,看起来像这样:

public static void Bind<T>(this Repeater rpt, IEnumerable<T> data)
{
rpt.DataSource = data;
rpt.DataBind();
}

这种方法需要一些努力,但由于独立于UI的数据访问逻辑位于一个单独的位置,因此可以更好地分离关注点(也许您还可以与不同客户端的其他项目共享数据访问代码,例如WPF或WinForms)。此外,我相信您将能够确定许多其他位置(除了数据绑定),在这些位置您也可以使用存储库,而不是直接访问数据。这也将使您的代码更短。

您可以在abc类中有一个函数,它接受中继器作为参数并将数据绑定到中继器。

编辑:您可能需要为不同的中继器切换数据源。在这种情况下,您可以向BindTable方法添加另一个参数,并在该方法内部检查该参数以切换到正确的数据源。

EDIT 2:BindTable接受两个参数,Repeater和一个枚举MyEnum

以下是我的操作方法。我有一个页面,Show.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Show.aspx.cs" Inherits="RepeaterTestOne.Show" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Repeater ID="rptDisplay" runat="server">
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:Label ID="lblID" runat="server" Text='<%#Eval("ID") %>'></asp:Label>
</td><td>
<asp:Label ID="lblName" runat="server" Text='<%#Eval("Name") %>'></asp:Label>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
<asp:Button ID="Button1" runat="server" Text="First One" OnClick="Button1_Click" />
<asp:Button ID="Button2" runat="server" Text="First Four" OnClick="Button2_Click" />
<asp:Button ID="Button3" runat="server" Text="All" OnClick="Button3_Click" />
</div>
</form>
</body>
</html>

在代码中,我调用数据类(MyDataClass)的BindTable()方法并传递中继器。我的Show.aspx。cs如下所示:

using System;
namespace RepeaterTestOne
{
public partial class Show : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
MyDataClass.BindTable(rptDisplay, MyEnum.FirstOne);
}
protected void Button2_Click(object sender, EventArgs e)
{
MyDataClass.BindTable(rptDisplay,MyEnum.FirstFour);
}
protected void Button3_Click(object sender, EventArgs e)
{
MyDataClass.BindTable(rptDisplay, MyEnum.AllItems);
}
}
}

在我的MyDataClass中,我有这样的代码(带有用于测试的伪代码):

using System.Collections.Generic;
using System.Web.UI.WebControls;
namespace RepeaterTestOne
{
public static class MyDataClass
{
public static void BindTable(Repeater rpt, MyEnum mySelection = MyEnum.AllItems)
{
//Replace this part with custom sql
List<MyData> lst = new List<MyData>()
{
new MyData{ID=1, Name="Item 1"},
new MyData{ID=2, Name="Item 2"},
new MyData{ID=3, Name="Item 3"},
new MyData{ID=4, Name="Item 4"},
new MyData{ID=5, Name="Item 5"}
};
switch (mySelection)
{
case MyEnum.FirstOne:
lst = new List<MyData>(){new MyData{ID=1, Name="Item 1"}};
break;
case MyEnum.FirstFour:
lst = new List<MyData>()
{
new MyData{ID=1, Name="Item 1"},
new MyData{ID=2, Name="Item 2"},
new MyData{ID=3, Name="Item 3"},
new MyData{ID=4, Name="Item 4"}
};
break;
default:
lst = new List<MyData>()
{
new MyData{ID=1, Name="Item 1"},
new MyData{ID=2, Name="Item 2"},
new MyData{ID=3, Name="Item 3"},
new MyData{ID=4, Name="Item 4"},
new MyData{ID=5, Name="Item 5"}
};
break;
}
//Replace this part with custom sql
rpt.DataSource = lst;
rpt.DataBind();
}
}
public class MyData
{
public int ID { get; set; }
public string Name { get; set; }
}
}

这是我的枚举MyEnum:

namespace RepeaterTestOne
{
public enum MyEnum
{
AllItems = 1,
FirstOne = 2,
FirstFour = 3
}
}

最新更新