【问题标题】:Generic Data Access Layer in an Multi-Layer Arcitechture多层架构中的通用数据访问层
【发布时间】:2011-08-18 13:03:51
【问题描述】:

我需要创建一个通用数据访问层以用于我在软件工程的最终作业,但我当前创建的数据访问层可以自动生成 CRUD(创建、读取、更新和删除)SQL 语句。我仍然需要定义数据库中的每个表,并且每次更改数据库时都需要定义数据访问层中的更改。

请查看我的代码示例并告诉我如何更改我的代码以改进我的访问层:

class sqlConn
{
    //Local
    private String strConn = @"Data Source=.\SQLEXPRESS;" +
        @"AttachDbFilename='D:\JP Stuff\BELGIUM CAMPUS\3de Jaar\SOFTWARE ENGINEERING\ASSIGNMENT\Premier Service Solutions\Premier Service Solutions\DB\db_PSS_1.0.mdf';" +
        @"Integrated Security=True;" +
        @"User Instance=True";
    private SqlConnection conn;

    //Properties
    public SqlConnection Conn
    {
        get { return this.conn = new SqlConnection(this.strConn); }
    }

    //Constructor
    public sqlConn()
    {

    }
}




class sqlFactory : sqlConn
{
    //Constructor
    public sqlFactory()
        : base()
    {

    }

    //Insert Record into database
    public void Create(String[] dbData, List<String> strRow)
    {
        using (SqlConnection sqlCon = this.Conn)
        using (SqlCommand com = new SqlCommand("SELECT * FROM " + dbData[0], sqlCon))
        {
            SqlDataAdapter da = new SqlDataAdapter(com);
            SqlCommandBuilder sqlbuilder = new SqlCommandBuilder(da);

            DataSet ds = new DataSet();
            da.Fill(ds, dbData[0]);

            DataRow dr = ds.Tables[dbData[0]].NewRow();

            for (int i = 0; i < dbData.Count() - 2; i++)
            {
                dr[i + 1] = strRow[i];
            }

            ds.Tables[dbData[0]].Rows.Add(dr);
            da.Update(ds, dbData[0]);
        }
    }
}

 class dbDefinitions : sqlFactory
 {
    public static Dictionary<String, String[]> columns;

    static dbDefinitions()
    {
        columns = new Dictionary<String,String[]>();

        //tblCall Definition
        #region call
        String[] data = new String[]
        { 
            "tblCall", "call_ID_PK", "call_emp_ID_FK", 
            "call_Description", "call_Notes", "call_Start_Time", 
            "call_End_Time", "call_Job_FK"
        };
        columns.Add("call", data);
        #endregion
    }
}

【问题讨论】:

  • 我做错了什么让我的帖子得到 n 个负面评价
  • 可能是因为这个问题有些模糊,很难选择一个确定的答案。换句话说,到目前为止,这里的每个答案都是有帮助的,但这是答案。

标签: c# data-access-layer


【解决方案1】:

这可能无法完全回答您的问题,但您可以通过多种方式改进此代码。

组合与继承

首先,了解和应用组合而不是继承。组合是“具有”关系,而继承是“是”关系。

例如,如果 Person 类具有 Phone 类类型的属性,则它是组合。

public class Person 
{
    public Phone Phone {get; set;}
}

如果 Person 类继承自 Phone 类,则它是继承。

public class Person : Phone
{
}

在您的代码中,sqlFactory 应该包含一个 sqlConn,而不是从它继承。

组合提供了更大的灵活性,尤其是因为 C# 不允许多重继承。阅读此处了解更多信息:Prefer composition over inheritance?

SQL 注入

你不应该像这样使用字符串连接来构建 sql 语句。

"SELECT * FROM " + dbData[0]

这会造成潜在的安全漏洞,允许 SQL 注入攻击。您应该始终使用参数化查询来防止这种情况发生。

阅读Tip/Trick: Guard Against SQL Injection Attacks,了解 SQL 注入攻击以及如何防止它们。

编码约定

C# 开发人员几乎普遍接受的类命名约定是使用 PascalCase,其中类名中每个单词的首字母大写。您的类将是 SqlFactory、SqlConn 和 DbDefinition。

本指南给出了相当常用的约定:C# Coding Standards document

【讨论】:

    【解决方案2】:

    您的 DAO 应该具有充当表模型的支持类。这些模型都应该有一个通用的接口。然后,您的 DAO 应该具有模型接口的实例,其中 XML 配置指向模型的正确表。这将使您不必在代码中定义表。您的数据访问层是访问您的数据的层,而不是定义您的数据的层。您的模型应该定义数据。

    【讨论】:

      【解决方案3】:

      尝试在 xml 文件中定义数据库架构信息并读取它以创建 CRUD 操作。

      【讨论】:

        猜你喜欢
        • 2015-06-17
        • 1970-01-01
        • 2013-02-02
        • 1970-01-01
        • 2014-10-01
        • 1970-01-01
        • 2019-07-31
        • 2014-01-10
        • 1970-01-01
        相关资源
        最近更新 更多