最近,一直在学习和摸索关于项目架构的东东。或许说架构说得有点太大。但是还是暂且用着吧。
也看看过几个高手关于三层架构和MVC模型的文章,觉得很多东西的理解和自己的不是很一样。但是自己确实没有他们研究的深入,所以也不妄加评论。
        在这里想说的是,自己幼稚的观点欢迎各位砸砖;自己绝对的言语只是针对自己的想法。
        我不是什么大虾,所以肯定没有架子,不会跟别人撑死争执,只会死缠着问。
      
          一、数据库设计的角度来说。个人的观点是数据库的设计应该是完全的面向需求和性能。而不应该考虑或是只是适当考虑代码设计的问题。 
                       表结构对程序的设计是有相当大的影响的。但是我们的表是根据需求来做的,同时考虑将来访问的性能问题。视图某种程度上是表 的延伸,但是他依赖表的设计。存储过程是业务逻辑一定程度上原始的表达。
          总结:数据库设计中对系统架构设计颇有影响的就是:表,视图,存储过程
                     其他的,比如约束,索引主要是维持表的完整性和提高数据读取的性能,对系统的结构影响甚微。
        恕我无知,我在做数据库设计是一般就是用到这么几个元素,其中索引用之很少。
       我是坚定的存储过程派(如果分派的话),在这里不去讨论两派的论战了。但是对存储过程的使用也是相当的有疑惑:
               1.存储过程抽空了业务逻辑的功能,让业务逻辑名存实亡;
               2.存储过程加大了数据与UI的耦合度(呵呵,不知道自己对耦合的理解对否?)
               3.项目中存储过程泛滥(很简单的SQL写成了存储过程,很多功能相似的存储过程)
               4.对于3采用动态存储过程,就出现耦合严重
         二、数据库访问层
              1. 看过好几个项目,看到别人的做法总是不厌其烦的用add方法向存储过程添加参数的时候,就在怀疑自己的做法是不很好。
我想为什么不做出一个通用的方法呢?
                             代码如下:
                  

1
using System;
  2
using System.Data;
  3
using System.Data.SqlClient;
  4

  5
namespace DB.Componse
  6
{
  7
        /**//// <summary>
  8
        ///基于SqlCilent的数据操作基类(全存储过程实现)
  9
        /// </summary>
 10
     public class SqlProcedure :IDisposable
 11
    
{
 12
         构造和声明#region  构造和声明
 13
         /**//// <summary>
 14
         /// 构造函数
 15
         /// </summary>
 16
         public SqlProcedure()
 17
         
{            
 18
         }
 19
         /**//// <summary>
 20
        /// 重构构造函数
 21
        /// 带有参数ConnStr(表示连接字符串)
 22
        /// </summary>
 23
        public SqlProcedure(string ConnStr)
 24
        
{
 25
            this.ConnStr = ConnStr;
 26
           // this.ConnOpen();数据库连接打开不必过早
 27
        }
 28
         /**//// <summary>
 29
         /// 析构函数
 30
         /// </summary>
 31
         ~SqlProcedure()
 32
         
{
 33
             this.ConnClose();
 34
             this.Dispose();
 35
         }
 36
         /**//// <summary>
 37
         /// 打开数据库连接
 38
         /// </summary>
 39
         private void ConnOpen()
 40
         
{
 41
             if (Conn == null)
 42
             
{
 43
                 //实例化数据库连接对象
 44
                 Conn = new SqlConnection(ConnStr);
 45
                 Conn.Open();
 46
             }
 47
         }
 48
         /**//// <summary>
 49
         /// 关闭数据库连接
 50
         /// </summary>
 51
         private void ConnClose()
 52
         
{
 53
             if (Conn != null)
 54
             
{
 55
                 Conn.Close();
 56
             }
 57
         }
 58
         /**//// <summary>
 59
         /// 释放数据库连接对象的资源
 60
         /// </summary>
 61
         public void Dispose()
 62
         
{
 63
             if (Conn != null)
 64
             
{
 65
                 Conn.Dispose();
 66
                 Conn = null;
 67
             }
 68
         }
 69
         /**//// <summary>
 70
         /// ConnStr:数据库连接字符串(私有字段)
 71
         /// Conn:数据库连接对象(私有对象)
 72
         /// </summary>
 73
         private string ConnStr;
 74
         private SqlConnection Conn;
 75
         #endregion
 76

 77
         数据库Command对象及参数对象的创建#region 数据库Command对象及参数对象的创建
 78
         /**//// <summary>
 79
         /// 创建一个依赖存储过程的Command对象(私有化)
 80
         /// </summary>
 81
         /// <param name="ProcName">欲调用的存储过程名</param>
 82
         /// <param name="Params">调用存储过程所需的参数集</param>
 83
         /// <returns>一个可使用的Command对象</returns>
 84
         private SqlCommand CreateComm(string ProcName,SqlParameter[] Params)
 85
         
{
 86
             //创建Command对象
 87
             this.ConnOpen();
 88
             SqlCommand Comm = new SqlCommand(ProcName,Conn);
 89
             Comm.CommandType = CommandType.StoredProcedure;
 90

 91
             //为其添加参数
 92
             if (Params!=null)
 93
             
{
 94
                 foreach (SqlParameter temp in Params)
 95
                 
{
 96
                     Comm.Parameters.Add(temp);
 97
                 }
 98
                 Comm.Parameters.Add(new SqlParameter
 99
                     ("ReturnValue", SqlDbType.Int, 4, ParameterDirection.ReturnValue, false, 0, 0,
100
                     String.Empty, DataRowVersion.Default, null));
101
              }
102
             return Comm;
103
         }
104
         /**//// <summary>
105
         /// 参数构造的基本方法(私有化)
106
         /// </summary>
107
         /// <param name="ParamName">参数名</param>
108
         /// <param name="dbType">参数在数据库中的类型</param>
109
         /// <param name="size">参数设置的最大大小</param>
110
         /// <param name="Value">参数的值(object类型)</param>
111
         /// <param name="direction">参数方向</param>
112
         /// <returns>参数对象</returns>
113
         private SqlParameter MakeParam(string ParamName,SqlDbType dbType,int size,object Value,ParameterDirection direction)
114
         
{
115
             SqlParameter Param = new SqlParameter(ParamName, dbType);
116
             if (size > 0)
117
             
{
118
                 Param.Size = size;
119
             }
120
             Param.Direction = direction;
121
             if (!(Value==null&&directinotallow==ParameterDirection.Output))
122
             
{
123
                 Param.Value = Value;
124
             }
125
             return Param;
126
         }
127
         /**//// <summary>
128
         /// 公开的传入参数方法
129
         /// </summary>
130
         /// <param name="ParamName">参数名</param>
131
         /// <param name="dbType">参数在数据库中的类型</param>
132
         /// <param name="size">参数设置的最大大小</param>
133
         /// <param name="Value">参数的值</param>
134
         /// <returns>参数对象</returns>
135
         public SqlParameter MakeInParam(string ParamName, SqlDbType dbType, int size, object Value)
136
         
{
137
             return MakeParam(ParamName, dbType, size, Value, ParameterDirection.Input);
138
         }
139
         /**//// <summary>
140
         /// 公开的传出参数方法
141
         /// </summary>
142
         /// <param name="ParamName">参数名</param>
143
         /// <param name="dbType">参数在数据库中的类型</param>
144
         /// <param name="size">参数设置的最大大小</param>
145
         /// <returns>参数对象</returns>
146
         public SqlParameter MakeOutParam(string ParamName, SqlDbType dbType, int size)
147
         
{
148
             return MakeParam(ParamName, dbType, size, null, ParameterDirection.Output);
149
         }
150
         #endregion
151
        
152
         数据库操作方法#region 数据库操作方法
153
         /**//// <summary>
154
         /// 运行带参数的存储过程,无数据返回
155
         /// </summary>
156
         /// <param name="ProcName">存储过程名</param>
157
         /// <param name="Params">参数集</param>
158
         /// <returns>受影响的行数</returns>
159
         public int ProcNonQuery(string ProcName, SqlParameter[] Params)
160
         
{
161
             SqlCommand myComm = CreateComm(ProcName, Params);
162
             this.ConnOpen();
163
             int i=myComm.ExecuteNonQuery();
164
             myComm.Parameters.Clear();
165
             this.ConnClose();
166
             //存在index为"ReturnValue"的参数
167
             //int i = Convert.ToInt32(myComm.Parameters["ReturnValue"].Value);
168
             return i;
169
         }
170
         /**//// <summary>
171
         /// 运行无参数的存储过程,无返回
172
         /// </summary>
173
         /// <param name="ProcName">存储过程名</param>
174
         /// <returns>返回受影响的行数</returns>
175
         public int ProcNonQuery(string ProcName)
176
         
{
177
             SqlCommand myComm = CreateComm(ProcName, null);
178
             this.ConnOpen();
179
             int i=myComm.ExecuteNonQuery();
180
             this.ConnClose();
181
             //存在index为"ReturnValue"的参数
182
             //int i = Convert.ToInt32(myComm.Parameters["ReturnValue"].Value);
183
             return i;
184
         }
185
         /**//// <summary>
186
         /// 执行无参存储过程,返回第一行数据
187
         /// </summary>
188
         /// <param name="ProcName">存储过程名</param>
189
         /// <returns>返回一个首行数据对象</returns>
190
         public object ProcScalar(string ProcName)
191
         
{
192
             SqlCommand myComm = CreateComm(ProcName, null);
193
             this.ConnOpen();
194
             object val = myComm.ExecuteScalar();
195
             this.ConnClose();
196
             return val;
197
         }
198
         /**//// <summary>
199
         /// 执行有参存储过程,返回第一行数据
200
         /// </summary>
201
         /// <param name="ProcName">存储过程名</param>
202
         /// <param name="Params">参数集</param>
203
         /// <returns>返回一个首行数据对象</returns>
204
         public object ProcScalar(string ProcName, SqlParameter[] Params)
205
         
{
206
             SqlCommand myComm = CreateComm(ProcName, Params);
207
             this.ConnOpen();
208
             object val=myComm.ExecuteScalar();
209
             myComm.Parameters.Clear();
210
             this.ConnClose();
211
             return val;
212
         }
213
         /**//// <summary>
214
         /// 运行无参数的存储过程,返回一个DataReader对象数据集
215
         /// </summary>
216
         /// <param name="ProcName">存储过程名</param>
217
         /// <param name="dr">DataReader对象</param>
218
         public void ProcReader(string ProcName, out SqlDataReader dr)
219
         
{
220
             SqlCommand myComm = CreateComm(ProcName, null);
221
             this.ConnOpen();
222
             dr = myComm.ExecuteReader(CommandBehavior.CloseConnection);
223
         }
224
         /**//// <summary>
225
         /// 运行带参数的存储过程,返回一个DataReader数据集
226
         /// </summary>
227
         /// <param name="ProcName">存储过程名</param>
228
         /// <param name="Params">参数集</param>
229
         /// <param name="dr">DataReader数据集</param>
230
         public void ProcReader(string ProcName,out SqlDataReader dr, SqlParameter[] Params)
231
         
{
232
             SqlCommand myComm = CreateComm(ProcName, Params);
233
             this.ConnOpen();
234
             dr = myComm.ExecuteReader(CommandBehavior.CloseConnection);
235
             myComm.Parameters.Clear();
236
            // dr = myComm.ExecuteReader();
237
             //this.ConnClose();
238
         }
239
         /**//// <summary>
240
         /// 运行带参数的存储过程,返回一个适配器对象DataAdapter
241
         /// </summary>
242
         /// <param name="ProcName">存储过程名</param>
243
         /// <param name="Params">参数集</param>
244
         /// <param name="da">适配器对象</param>
245
         public void ProcAapter(string ProcName, SqlParameter[] Params, out SqlDataAdapter da)
246
         
{
247
             SqlCommand myComm = CreateComm(ProcName, Params);
248
             this.ConnOpen();
249
             SqlDataAdapter sda = new SqlDataAdapter(myComm);
250
             myComm.Parameters.Clear();
251
             this.ConnClose();
252
             da = sda;
253
         }
254
         /**//// <summary>
255
         /// 运行无参存储过程,返回适配器对象DataAdapter
256
         /// </summary>
257
         /// <param name="ProcName">存储过程名</param>
258
         /// <param name="da">适配器对象DataAdapter</param>
259
         public void ProcAapter(string ProcName, out SqlDataAdapter da)
260
         
{
261
             SqlCommand myComm = CreateComm(ProcName, null);
262
             this.ConnOpen();
263
             SqlDataAdapter sda = new SqlDataAdapter(myComm);
264
             this.ConnClose();
265
             da = sda;
266
         }
267
         #endregion
268
     }
269
}
270

                2.看到经典的petshop4.0中,数据库访问层返回的都是DataReader对象,这样确实很好。但是如果我的一个方法中除了要求返回若干数据集,还要返回传出参数,那怎么办呢?
                      (我的做法是在数据库访问层中先将DataReader中的数据转移),这样感觉有点不伦不类了。
              3.对于这层,现在大虾的做法是用ORM直接生成,所以我想在这层中应该是相当的成熟了。所以很想知道那些比较优良的解决方案。