简体   繁体   English

asp.net中DataBinding的可维护性最佳实践

[英]Best practices for DataBinding in asp.net for maintainability

I would like to know what are the best practices for using asp.net DataBinding, in terms of maintainability. 我想知道在可维护性方面使用asp.net DataBinding的最佳实践是什么。

I don't want the application to fall appart when I have to make changes to the database. 当我必须对数据库进行更改时,我不希望应用程序崩溃。

Should I databind completely in codebehind ? 我应该完全在代码隐藏中进行数据绑定吗? I am planning on using ObjectDataSources for the databinding. 我打算使用ObjectDataSources进行数据绑定。 Is there something that is easier to maintain than using databinding, if so, what is it ? 是否存在比使用数据绑定更容易维护的东西,如果是这样,它是什么?

Are there considerations, I should take into account when designing my data access layer and my business layer ? 是否有考虑因素,在设计数据访问层和业务层时应考虑到这些因素?

Thanks. 谢谢。

My philosophy on this is that data access stuff has no business in the markup. 我的理念是数据访问内容在标记中没有业务。 Object Data Sources are better then SQL Data Sources, but I like to keep my markup as only stuff that will get rendered on to the page. 对象数据源比SQL数据源更好,但我喜欢将我的标记保留为只会呈现在页面上的内容。 I also prefer the control you have on what stuff is databound that you get from always doing it from the code behind. 我也更喜欢你控制的东西是你从后面的代码总是做的数据绑定。

Good question! 好问题!

As far as databinding goes, you should look at it as only one component of your overall data access strategy. 就数据绑定而言,您应将其视为整体数据访问策略的一个组成部分。 My strategy has three components (I get to your DataBinding in component 2): 我的策略有三个组件(我在组件2中找到了你的DataBinding):

First, I always create (or reuse, mostly) a Data Access Layer (DAL) to simplify data access. 首先,我总是创建(或主要重用)数据访问层(DAL)以简化数据访问。 This is not because I may someday swap out your database for another - the chances of that are slim enough that it doesn't warrant all the work that'd be required (YAGNI). 不是因为我有一天可能会将你的数据库替换为另一个数据库 - 这种可能性足够小,以至于它不能保证所有需要的工作(YAGNI)。 You do this so that you can A) remove all of the clutter from normal database code (eg getting the connection string, setting up and closing connections, etc.) and B) simplify common operations with dedicated functions. 这样做是为了你可以A)从正常的数据库代码中删除所有混乱(例如获取连接字符串,设置和关闭连接等)和B)使用专用函数简化常见操作。

Second, you absolutely should implement ObjectDataSources that encapsulate the DataBinding for your UI controls. 其次,您绝对应该实现为您的UI控件封装DataBinding的ObjectDataSources。 If you've built a good DAL, this becomes pretty trivial. 如果你已经建立了一个好的DAL,这变得非常简单。 For example, here is a ObjectDataSource that uses my 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>();
        }
    }

A few things to note: the "DataObjectMethodAttribute" attribute will make this method visible to the design-time environment so that you'll see it in the pull-down list of data sources when you go to link up your Grid (or whatever). 需要注意的一点是:“DataObjectMethodAttribute”属性将使此方法对设计时环境可见,这样当您连接Grid(或其他)时,您将在数据源的下拉列表中看到它。 You'll also need the [DataObjectAttribute] attribute on the class that provides this method (this class if part of my Business Layer). 您还需要提供此方法的类的[DataObjectAttribute]属性(此类是我的业务层的一部分)。 Finally, this is a pretty simple example and doesn't have some common constructs such as startRowIndex and maximumRows parameters for returning paged results. 最后,这是一个非常简单的示例,并且没有一些常见的结构,例如startRowIndex和maximumRows参数,用于返回分页结果。

Note that the particular call here is from my DAL - it is not LinqToSQL even though it has a surface similarity. 请注意,此处的特定调用来自我的DAL - 即使它具有表面相似性,它也不是LinqToSQL。 I like SQL and I don't want C# idioms that just have an arbitrary mapping back to SQL anyway . 我喜欢SQL,我不希望 C#习惯用法反正只有SQL的任意映射 Note that if I attempted to implement all of this in straight ADO calls, this function would be three times as long and have LOTS of code that really wasn't germane to expressing my goals. 请注意,如果我尝试在直接ADO调用中实现所有这些,那么这个函数将是三倍长,并且有很多代码与表达我的目标没有密切关系。

Third, I always place multistep database operations in stored procedures to minimize the number of calls over the wire to the database. 第三,我总是在存储过程中放置​​多步数据库操作,以最大限度地减少通过数据线连接的调用次数。 For example, I provide a "Check In" feature in one product that takes a check in request, checks it against a membership table, retrieves previous check in history (how many visits in the last month?), awards incentive points if appropriate, etc. etc. Running multiple queries and changes to the database in C# code would be horribly complex and quite expensive. 例如,我在一个产品中提供“检入”功能,该功能接受检入请求,根据成员资格表进行检查,检索以前的检入历史记录(上个月有多少次访问?),如果合适,奖励激励点,在C#代码中运行多个查询和对数据库的更改将非常复杂且非常昂贵。 In keeping with our DAL philosophy, I also encapsulate the call to the stored procedure in my DAL so that the actual call from code is just: 为了与DAL理念保持一致,我还将调用封装在DAL中的存储过程中,以便代码的实际调用只是:

int status = dal.CheckIn(userID, ref checkInHistory); int status = dal.CheckIn(userID,ref checkInHistory);

As you can see, using a stored procedure and encapsulating it in a C# class method also makes the code far easier to read. 正如你所看到的,使用存储过程,并在C#类方法封装它也使代码容易阅读。 My code just says what it does (as above) rather than having 100+ lines of code setting up queries, etc. 我的代码只是说它做了什么(如上所述),而不是有100多行代码设置查询等。

I hope that this helps! 我希望这个对你有用!

Just for the sake of completeness, I want to add this about my comment in first answer. 仅仅为了完整起见,我想在第一个答案中添加关于我的评论。

I asked the following question: 我问了以下问题:

if you databind from codebehind, you will still have to define your fields in the markup. 如果你从代码隐藏数据绑定,你仍然需要在标记中定义你的字段。 How would you make sure that changes in your business objects won't break the pages ? 您如何确保业务对象中的更改不会破坏页面?

When Databinding, if you cast your object, it will be detected at compile time, if a property name has changed or if it no longer exists. 当数据绑定时,如果你转换了对象,它将在编译时检测,如果属性名称已更改或不再存在。

Exemple: 例:

<%# ((ObjetType)Container.DataItem).PropertyName %>

Also, doing this, will avoid the use of Eval, which is reported to be slow because it uses reflection. 此外,这样做,将避免使用Eval,因为它使用反射,因此报告速度很慢。 (Didn't really check the performance impact myself) (没有真正检查自己的性能影响)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM