我想知道在可维护性方面使用 asp.net DataBinding 的最佳实践是什么。
当我必须对数据库进行更改时,我不希望应用程序崩溃。
我应该在代码隐藏中完全绑定数据吗?我计划使用 ObjectDataSources 进行数据绑定。有没有比使用数据绑定更容易维护的东西,如果有,它是什么?
在设计我的数据访问层和业务层时,我应该考虑哪些因素?
谢谢。
我想知道在可维护性方面使用 asp.net DataBinding 的最佳实践是什么。
当我必须对数据库进行更改时,我不希望应用程序崩溃。
我应该在代码隐藏中完全绑定数据吗?我计划使用 ObjectDataSources 进行数据绑定。有没有比使用数据绑定更容易维护的东西,如果有,它是什么?
在设计我的数据访问层和业务层时,我应该考虑哪些因素?
谢谢。
我的理念是数据访问的东西在标记中没有业务。对象数据源比 SQL 数据源更好,但我喜欢将我的标记保留为只会呈现到页面上的内容。我也更喜欢你对哪些东西是数据绑定的控制,你总是从后面的代码中得到它。
好问题!
就数据绑定而言,您应该仅将其视为整体数据访问策略的一个组成部分。 我的策略包含三个组件(我在组件 2 中找到您的 DataBinding):
首先,我总是创建(或重用)数据访问层 (DAL) 以简化数据访问。这并不是因为有一天我可能会将您的数据库换成另一个 - 这种可能性很小,以至于它不能保证所需的所有工作(YAGNI)。这样做是为了 A) 消除正常数据库代码中的所有杂乱(例如获取连接字符串、设置和关闭连接等)和 B) 使用专用函数简化常见操作。
其次,您绝对应该实现为您的 UI 控件封装 DataBinding 的 ObjectDataSource。如果您构建了一个好的 DAL,这将变得非常简单。例如,这是一个使用我的 DAL 的 ObjectDataSource:
[DataObjectMethodAttribute(DataObjectMethodType.Select, true)]
public List<EnrollListMemberData> GetNameList(int classID, DateTime classDate)
{
using (BSDIQuery qry = new BSDIQuery())
{
return
qry.Command(
"Select a.ClassDate, a.ClientID, b.FirstName, b.LastName, b.ID From ClassEnroll a inner join Folder b on (a.ClientID = b.ClientID) Where (a.ClassID=@ClassID) AND ")
.ParamVal(classID)
.Append("(DateDiff(d, a.ClassDate, @ClassDate) = 0) Order By LastName;")
.ParamVal(classDate)
.ReturnList<EnrollListMemberData>();
}
}
需要注意的几点:“DataObjectMethodAttribute”属性将使该方法对设计时环境可见,以便在链接网格(或其他)时在数据源的下拉列表中看到它. 您还需要提供此方法的类的 [DataObjectAttribute] 属性(如果该类是我的业务层的一部分)。最后,这是一个非常简单的示例,并且没有一些常见的构造,例如用于返回分页结果的 startRowIndex 和 maximumRows 参数。
请注意,这里的特定调用来自我的 DAL - 它不是 LinqToSQL,即使它具有表面相似性。我喜欢 SQL,而且我不希望C# 惯用语有任意映射回 SQL。请注意,如果我试图在直接的 ADO 调用中实现所有这些,那么这个函数的长度将是原来的三倍,并且有很多代码与表达我的目标并不密切相关。
第三,我总是将多步数据库操作放在存储过程中,以尽量减少通过线路调用数据库的次数。例如,我在一个产品中提供了“签到”功能,它接受签到请求,根据会员表检查它,检索以前的签到历史记录(上个月有多少访问?),如果合适,奖励奖励积分,等等等等。在 C# 代码中运行多个查询和对数据库的更改将非常复杂且非常昂贵。为了与我们的 DAL 理念保持一致,我还将对存储过程的调用封装在我的 DAL 中,以便来自代码的实际调用只是:
int status = dal.CheckIn(userID, ref checkInHistory);
如您所见,使用存储过程并将其封装在 C# 类方法中也使代码更易于阅读。我的代码只是说明了它的作用(如上所述),而不是有 100 多行代码设置查询等。
我希望这个对你有用!
只是为了完整起见,我想在第一个答案中添加关于我的评论。
我问了以下问题:
如果您从代码隐藏中进行数据绑定,您仍然必须在标记中定义您的字段。您将如何确保业务对象中的更改不会破坏页面?
当数据绑定时,如果你转换你的对象,它会在编译时被检测到,如果一个属性名称已经改变或者它不再存在。
示例:
<%# ((ObjetType)Container.DataItem).PropertyName %>
Also, doing this, will avoid the use of Eval, which is reported to be slow because it uses reflection. (Didn't really check the performance impact myself)