在C#中访问数据库的最佳方法(设计模式)是什么?

在C#中访问数据库的最佳方法(设计模式)是什么?,c#,database,visual-studio,design-patterns,C#,Database,Visual Studio,Design Patterns,我是设计模式的新手。 目前,我正在开发一个系统,我有一个relation数据库。从数据库中获取CRUD的最佳方法是什么? 我当前的代码如下所示(C代码): 我为所有类定义了一个带有commons函数的接口 namespace Model { public interface ICommon { void insert(); void update(); void delete(); } } 公共类(抽象类)实现ICommo

我是设计模式的新手。 目前,我正在开发一个系统,我有一个relation数据库。从数据库中获取CRUD的最佳方法是什么? 我当前的代码如下所示(C代码):

我为所有类定义了一个带有commons函数的接口

namespace Model
{
    public interface ICommon
    {
        void insert();
        void update();
        void delete();
    }
}
公共类(抽象类)实现ICommon接口和少量的orders方法和属性

namespace Model
{
    public abstract class Common : ICommon
    {
        public Guid RecId { set; get; }

        public abstract void insert();
        public abstract void update();
        public abstract void delete();
        public abstract List<Common> find();

        /// <summary>
        /// Insert or update the record
        /// </summary>
        public void save()
        {
            if (this.RecId == Guid.Empty)
            {
                this.insert();
            }
            else
            {
                this.update();
            }
        }
    }
}
名称空间模型
{
公共抽象类Common:ICommon
{
公共Guid RecId{set;get;}
公共摘要无效插入();
公共摘要无效更新();
公共摘要作废删除();
公共摘要列表查找();
/// 
///插入或更新记录
/// 
公共作废保存()
{
if(this.RecId==Guid.Empty)
{
这是insert();
}
其他的
{
这个.update();
}
}
}
}
然后,适当的类(例如UserTable类)扩展公共类并实现抽象方法和其他属性

namespace Model
{
    public abstract class Common : ICommon
    {
        public Guid RecId { set; get; }

        public abstract void insert();
        public abstract void update();
        public abstract void delete();
        public abstract List<Common> find();

        /// <summary>
        /// Insert or update the record
        /// </summary>
        public void save()
        {
            if (this.RecId == Guid.Empty)
            {
                this.insert();
            }
            else
            {
                this.update();
            }
        }
    }
}
我从StoresProcedures和SqlParameter、SqlCommand和SqlConnection执行CRUD的方式。这是一个例子:

    class CustTableModel : Common
        {
            public string SerialNumber { set; get; }
            public string ApplicationVersion { set; get; }
            public string KernelVersion { set; get; }
            public string Name { set; get; }
            public bool Active { set; get; }

            public override void insert()
            {
                List<SqlParameter> parameters = new List<SqlParameter>();
                SqlParameter parameter;

                // SerialNumber
                parameter = new SqlParameter("@serialNumber", System.Data.SqlDbType.Int);
                parameter.Value = this.SerialNumber;
                parameters.Add(parameter);

                // ApplicationVersion
                parameter = new SqlParameter("@applicationVersion", System.Data.SqlDbType.Int);
                parameter.Value = this.ApplicationVersion;
                parameters.Add(parameter);

                // KernelVersion
                parameter = new SqlParameter("@kernelVersion", System.Data.SqlDbType.Int);
                parameter.Value = this.KernelVersion;
                parameters.Add(parameter);

                // Name
                parameter = new SqlParameter("@name", System.Data.SqlDbType.Int);
                parameter.Value = this.Name;
                parameters.Add(parameter);

                // Active
                parameter = new SqlParameter("@active", System.Data.SqlDbType.Bit);
                parameter.Value = this.Active;
                parameters.Add(parameter);

                DBConn.execute("CUSTTABLE_INSERT", parameters); // The code of DBConn is below.
}
}
class CustTableModel:通用
{
公共字符串序列号{set;get;}
公共字符串应用程序版本{set;get;}
公共字符串内核版本{set;get;}
公共字符串名称{set;get;}
公共布尔活动{set;get;}
公共覆盖无效插入()
{
列表参数=新列表();
SqlParameter参数;
//序列号
parameter=newsqlparameter(“@serialNumber”,System.Data.SqlDbType.Int);
parameter.Value=this.SerialNumber;
参数。添加(参数);
//应用程序版本
parameter=newsqlparameter(“@applicationVersion”,System.Data.SqlDbType.Int);
parameter.Value=this.ApplicationVersion;
参数。添加(参数);
//核变异
parameter=newsqlparameter(“@kernelVersion”,System.Data.SqlDbType.Int);
parameter.Value=this.KernelVersion;
参数。添加(参数);
//名字
parameter=newsqlparameter(“@name”,System.Data.SqlDbType.Int);
parameter.Value=this.Name;
参数。添加(参数);
//活跃的
参数=新的SqlParameter(“@active”,System.Data.SqlDbType.Bit);
parameter.Value=this.Active;
参数。添加(参数);
execute(“custable_INSERT”,parameters);//DBConn的代码如下。
}
}
为了更好地理解,这里是DBConn类:

public class DBConn
    {
        protected SqlConnection sqlConnection;
        protected string command { set; get; }
        protected List<SqlParameter> parameters { set; get; }

        protected void openConnection()
        {
            this.sqlConnection = new SqlConnection();
            this.sqlConnection.ConnectionString = "Data Source=.\\SQLEXPRESS;Initial Catalog=JYL_SOAWS_DB;Integrated Security=True";
            this.sqlConnection.Open();
        }

        protected void closeConnection()
        {
            if (this.sqlConnection.State == System.Data.ConnectionState.Open)
            {
                this.sqlConnection.Close();
            }
        }

        /// <summary>
        /// Executa o processo no banco.
        /// </summary>
        /// <returns>Quantidade de registros afetados.</returns>
        protected SqlDataReader run()
        {
            SqlCommand command = new SqlCommand();
            SqlDataReader ret;

            this.openConnection();

            command.CommandType = System.Data.CommandType.StoredProcedure;
            command.Connection = this.sqlConnection;
            command.CommandText = this.command;

            if (this.parameters != null)
            {
                foreach (SqlParameter parameter in this.parameters)
                {
                    command.Parameters.Add(parameter);
                }
            }

            ret = command.ExecuteReader();

            this.closeConnection();

            return ret;
        }

        /// <summary>
        /// Interface da classe à outros objetos.
        /// </summary>
        /// <param name="commandName">Nome da store procedure a ser executada.</param>
        /// <param name="parameters">A lista com os parâmetros e valores.</param>
        /// <returns>Numero de registros afetados.</returns>
        public static SqlDataReader execute(string commandName, List<SqlParameter> parameters = null)
        {
            DBConn conn = new DBConn();

            conn.command = commandName;
            conn.parameters = parameters;

            return conn.run();
        }
    }
公共类DBConn
{
受保护的SqlConnection-SqlConnection;
受保护的字符串命令{set;get;}
受保护的列表参数{set;get;}
受保护的void openConnection()
{
this.sqlConnection=新的sqlConnection();
this.sqlConnection.ConnectionString=“数据源=。\\SQLEXPRESS;初始目录=JYL\u SOAWS\u DB;集成安全性=True”;
this.sqlConnection.Open();
}
受保护的void closeConnection()
{
if(this.sqlConnection.State==System.Data.ConnectionState.Open)
{
this.sqlConnection.Close();
}
}
/// 
///执行无银行流程。
/// 
///注册数量。
受保护的SqlDataReader运行()
{
SqlCommand=newsqlcommand();
SqlDataReader-ret;
这个.openConnection();
command.CommandType=System.Data.CommandType.StoredProcess;
command.Connection=this.sqlConnection;
command.CommandText=this.command;
如果(this.parameters!=null)
{
foreach(此.parameters中的SqlParameter参数)
{
command.Parameters.Add(参数);
}
}
ret=command.ExecuteReader();
这个.closeConnection();
返回ret;
}
/// 
///输出对象的类接口。
/// 
///Nome da存储过程a ser executada。
//一个Listacom操作系统。
///登记号码。
公共静态SqlDataReader执行(字符串commandName,列表参数=null)
{
DBConn conn=新的DBConn();
conn.command=commandName;
连接参数=参数;
返回连接运行();
}
}
我确信有更好的办法


有人能帮我吗?感谢是进步。

您在这里发现了两种微妙不同的模式

第一种是-一种从数据访问中抽象出业务逻辑的方法

第二种是模式,实体负责在数据库中维护自己的状态

我建议您远离C#中的ActiveRecord(您现在可能知道也可能不知道该模式,但它非常有用,并且与AR相当不兼容)

我建议你考虑一下,如果你刚开始的话(我仍然在我的小项目中使用它)。这是一个微型ORM,它从使用数据库中带走了大量的样板文件,并没有固执己见或难以学习(我使用并喜欢EntityFramework和NHibernate,但对于初学者来说,它们并不是很容易学会的)

除此之外,我还将创建一个存储库(一个具有create(Foo实体)、Read(Guid entityId)、Update(Foo实体)和Delete(Guid)的类)