public class ServiceDal : IServiceDal
    {
        public static readonly string Customers = ConfigurationManager.ConnectionStrings["Customers"].ToString();// Get the connection string in the configuration file
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public bool Add<T> (T t) where T : BaseModel
        {
            Type type = typeof(T);
            object oCompany = Activator.CreateInstance(type);
            // The Richard Id is automatically incremented, so the SQL statement should remove the Id field
            / / Richard GetProperties (BindingFlags. Public | BindingFlags. Instance | BindingFlags. DeclaredOnly) filter out the attribute of inherited from the superclass
            string props = string.Join(",", type.GetProperties().Where(p => ! p.Name.Equals("Id"))
                //GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)  
                .Select(a => $" [{a.Name}]. ""));
            string paraValues = string.Join(",", type.GetProperties().Where(p => ! p.Name.Equals("Id"))
               //GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)  
               .Select(a => $" @ [{a.Name}]. ""));
            string sql = $"Insert [{type.Name}] ({props}) values({paraValues})";
            var parameters = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly).Select(item => new SqlParameter()
            {
                ParameterName = $" @{item.Name}",
                SqlValue = $"{item.GetValue(t)}"
            });
            // Select * from SQL where ID is Int; // Select * from SQL where ID is Int
            // prevent SQL injection
            using (SqlConnection connection = new SqlConnection(Customers))
            {
                SqlCommand sqlCommand = new SqlCommand(sql, connection);

                sqlCommand.Parameters.AddRange(parameters.ToArray());
                connection.Open();
                return sqlCommand.ExecuteNonQuery() > 0; }}/// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public bool Delete<T> (T t) where T : Advanced.Model.BaseModel
        {
            Type type = t.GetType(); 
            string sql = SqlBuilder<T>.DeleteSql; 
            //string sql = $"Delete from [{type.Name}] where Id=@Id";
            using (SqlConnection connection = new SqlConnection(Customers))
            {
                SqlCommand sqlCommand = new SqlCommand(sql, connection);
                sqlCommand.Parameters.Add(new SqlParameter("@Id", t.Id));
                connection.Open();
                return sqlCommand.ExecuteNonQuery() > 0; }}/// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id"></param>
        /// <returns></returns>
        public T Find<T> (int id) where T : BaseModel
        {
            Type type = typeof(T);
            object oCompany = Activator.CreateInstance(type);

            //string sql = $"SELECT {string.Join(",", type.GetProperties().Select(a => $"[{a.Name}]")) } FROM [{type.Name}] where Id=@Id";

            string sql = SqlBuilder<T>.FindSql;


            // Select * from SQL where ID is Int; // Select * from SQL where ID is Int
            // prevent SQL injection
            using (SqlConnection connection = new SqlConnection(Customers))
            {
                SqlCommand sqlCommand = new SqlCommand(sql, connection);
                sqlCommand.Parameters.Add(new SqlParameter("@Id", id));
                connection.Open();
                SqlDataReader reader = sqlCommand.ExecuteReader();
                if (reader.Read()) // Start reading
                {
                    ReaderToList(type, oCompany, reader);
                    return (T)oCompany;
                }
                else  //Richard
                {
                    return null; }}}#region Private
        private static void ReaderToList(Type type, object oCompany, SqlDataReader reader)
        {
            foreach (var prop in type.GetProperties())
            {
                //Richard DBnull
                prop.SetValue(oCompany, reader[prop.Name] is DBNull ? null: reader[prop.Name]); }}#endregion

        /// <summary>
        ///Check all
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public List<T> FindAll<T> () where T : Advanced.Model.BaseModel
        {
            Type type = typeof(T);
            //string sql = $"SELECT {string.Join(",", type.GetProperties().Select(a => $"[{a.Name}]")) } FROM [{type.Name}]";

            string sql = SqlBuilder<T>.FindAllSql;

            using (SqlConnection connection = new SqlConnection(Customers))
            {
                SqlCommand sqlCommand = new SqlCommand(sql, connection);

                connection.Open();
                SqlDataReader reader = sqlCommand.ExecuteReader();
                List<T> datalist = new List<T>();
                while (reader.Read()) // Start reading
                {
                    object oCompany = Activator.CreateInstance(type);
                    ReaderToList(type, oCompany, reader);
                    datalist.Add((T)oCompany);
                }
                returndatalist; }}/// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public bool Update<T> (T t) where T : Advanced.Model.BaseModel
        {
            Type type = typeof(T);
            object oCompany = Activator.CreateInstance(type);
            //string sql = $"update [{type.Name}] set {string.Join(",", type.GetProperties().Where(a => ! a.Name.Equals("Id")).Select(a => $"[{a.Name}]=@ {a.Name}"))} where Id =@Id";
            string sql = SqlBuilder<T>.UpdateSql;
            var parameters = type.GetProperties().Select(item => new SqlParameter()
            {
                ParameterName = $" @{item.Name}",
                SqlValue = $"{item.GetValue(t)}"
            });
            // Select * from SQL where ID is Int; // Select * from SQL where ID is Int
            // prevent SQL injection
            using (SqlConnection connection = new SqlConnection(Customers))
            {
                SqlCommand sqlCommand = new SqlCommand(sql, connection);

                sqlCommand.Parameters.AddRange(parameters.ToArray());
                connection.Open();
                return sqlCommand.ExecuteNonQuery() > 0; }}}Copy the code
public class ConfigHelper
    {
        public static readonly string factoryConfig= ConfigurationManager.AppSettings["factoryConfig"]; }}Copy the code
/// <summary>
    ///Make copies for different types
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class SqlBuilder<T> where T : BaseModel
    { 
        public static readonly string FindSql = null;
        public static readonly string DeleteSql = null;
        public static readonly string FindAllSql = null;
        public static readonly string UpdateSql = null;

        static SqlBuilder()
        {
            Type type = typeof(T);
            FindSql = $"SELECT {string.Join(",", type.GetProperties().Select(a => $" [{a.Name}]. ""))} FROM [{type.Name}] where Id=@Id";

            DeleteSql = $"Delete from [{type.Name}] where Id=@Id"; ;
            FindAllSql = $"SELECT {string.Join(",", type.GetProperties().Select(a => $" [{a.Name}]. ""))} FROM [{type.Name}]. "";
            UpdateSql = $"update [{type.Name}]  set {string.Join(",", type.GetProperties().Where(a => ! a.Name.Equals("Id")).Select(a => $" [{a.Name}] = @{a.Name}"))}  where Id =@Id"; }}Copy the code