May*_*ayo 4 sql asp.net database-design design-patterns data-modeling
我们的团队被要求为现有的SQL Server后端编写Web接口,该后端源于Access.
其中一个要求/约束是我们必须限制对SQL后端的更改.我们可以创建视图和存储过程,但是我们已经被要求按原样保留表/列.
SQL后端不太理想.由于缺少外键,大多数关系都是隐含的.有些表缺少主键.表和列名称不一致,包括空格,斜杠和井号等字符.
除了找到一份新工作或要求他们重新考虑这一要求之外,任何人都可以提供任何解决这一缺陷的良好模式吗?
注意:我们将使用SQL Server 2005和ASP.NET与.NET Framework 3.5.
观点和同义词可以帮助你到目前为止,但修复底层结构显然需要更多的工作.
我当然会再次尝试说服利益相关者通过不解决他们正在产生技术债务的潜在问题,这将使代码的速度变慢,最终达到债务可能致残的程度.虽然你可以解决它,但债务将在那里.
即使使用数据访问层,如果您尝试扩展,数据库中的基础问题(例如您提到的键/索引)也会导致问题.
简单:确保您拥有强大的数据访问和业务逻辑层.您必须避免从ASPX代码隐藏直接编程到数据库的诱惑!
即使有一个强大的数据库架构,我现在使它成为一个惯例从来没有使用SQL在codebehinds工作 - 只有学习困难的方式,它有它的缺点后开发的实践.
以下是一些有助于此过程的提示:
首先,研究ObjectDataSource类.它将允许您构建一个强大的BLL,它仍然可以在不使用直接SQL的情况下提供GridView之类的控件.它们看起来像这样:
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" 
    OldValuesParameterFormatString="original_{0}" 
    SelectMethod="GetArticles"   <-- The name of the method in your BLL class 
    OnObjectCreating="OnObjectCreating"   <-- Needed to provide an instance whose constructor takes arguments (see below)
    TypeName="MotivationBusinessModel.ContentPagesLogic">  <-- The BLL Class
    <SelectParameters>
        <asp:SessionParameter DefaultValue="News" Name="category" <-- Pass parameters to the method
            SessionField="CurPageCategory" Type="String" />
    </SelectParameters>
</asp:ObjectDataSource>
如果构造BLL类的实例需要传递参数,则需要OnObjectCreating链接.在您的代码隐藏中,实现如下:
    public void OnObjectCreating(object sender, ObjectDataSourceEventArgs e)
    {
        e.ObjectInstance = new ContentPagesLogic(sessionObj);
    }
接下来,实现BLL需要更多的东西,我将为您节省谷歌搜索的麻烦.这是一个与上述调用相匹配的实现.
namespace MotivationBusinessModel   <-- My business model namespace
{
    public class ContentPagesItem  <-- The class that "stands in" for a table/query - a List of these is returned after I pull the corresponding records from the db
    {
        public int UID { get; set; }
        public string Title { get; set; }  <-- My DAL requires properties but they're a good idea anyway
        ....etc...
    }
    [DataObject]  <-- Needed to makes this class pop up when you are looking up a data source from a GridView, etc.
    public class ContentPagesLogic : BusinessLogic
    {
        public ContentPagesLogic(SessionClass inSessionObj) : base(inSessionObj)
        {
        }
        [DataObjectMethodAttribute(DataObjectMethodType.Select, true)]  <-- Needed to make this *function* pop up as a data source
        public List<ContentPagesItem> GetArticles(string category)  <-- Note the use of a generic list - which is iEnumerable
        {
            using (BSDIQuery qry = new BSDIQuery())  <-- My DAL - just for perspective
            {
                return
                    qry.Command("Select UID, Title, Content From ContentLinks ")
                        .Where("Category", category)
                        .OrderBy("Title")
                        .ReturnList<ContentPagesItem>();
                 // ^-- This is a simple table query but it could be any type of join, View or sproc call. 
            }
        }
     }
 }
其次,很容易将DAL/BLL dll作为附加项目添加到项目中,然后添加对主Web项目的引用.这样做不仅可以为您的DAL和BLL提供自己的身份,而且还可以轻松实现单元测试.
第三,我几乎不愿意承认它,但这可能是微软实体框架派上用场的地方.我通常不喜欢Linq to Entities,但它确实允许您在数据库中缺少的数据关系的代码端规范.
最后,我可以看到为什么更改你的数据库结构(例如移动字段)会有问题但是添加新约束(尤其是索引)不应该.他们是否担心外键最终会导致其他软件出错?如果是这样......这不是一件好事; 你必须要有一些痛苦才能知道疾病所处的位置,不是吗?
至少,出于性能原因,您应该根据需要推动添加索引的能力.此外,我同意其他人认为,观点可以大大有助于使结构更加明智.但是,从长远来看,这还不够.所以...继续构建视图(存储过程),但你仍然应该避免直接编码到数据库.否则,您仍然将实现锚定到数据库模式,并且将来比将数据库交互隔离到DAL更难.
| 归档时间: | 
 | 
| 查看次数: | 402 次 | 
| 最近记录: |