您现在的位置是:首页 > .NET

.NET

.net中Attribuge的详细应用(四)

2020-11-15 10:37:34 .NET admin
SqlCommandGenerator类的设计SqlCommandGEnerator类的设计思路就是通过反射得到方法的参数,使用被SqlCommandParameterAttribute标记的参数来装配一个Command实例。引用的命名空间
SqlCommandGenerator类的设计

SqlCommandGEnerator类的设计思路就是通过反射得到方法的参数,使用被SqlCommandParameterAttribute标记的参数来装配一个Command实例。

引用的命名空间:
//SqlCommandGenerator.cs

usingSystem;
usingSystem.Reflection;
usingSystem.Data;
usingSystem.Data.SqlClient;
usingDebug=System.Diagnostics.Debug;
usingStackTrace=System.Diagnostics.StackTrace;

类代码:
namespaceDataAccess
{
publicsealedclassSqlCommandGenerator
{
//私有构造器,不允许使用无参数的构造器构造一个实例
privateSqlCommandGenerator()
{
thrownewNotSupportedException();
}

//静态只读字段,定义用于返回值的参数名称
publicstaticreadonlystringReturnValueParameterName="RETURN_VALUE";
//静态只读字段,用于不带参数的存储过程
publicstaticreadonlyobject[]NoValues=newobject[]{};


publicstaticSqlCommandGenerateCommand(SqlConnectionconnection,
MethodInfomethod,object[]values)
{
//如果没有指定方法名称,从堆栈帧得到方法名称
if(method==null)
method=(MethodInfo)(newStackTrace().GetFrame(1).GetMethod());

//获取方法传进来的SqlCommandMethodAttribute
//为了使用该方法来生成一个Command对象,要求有这个Attribute。
SqlCommandMethodAttributecommandAttribute=
(SqlCommandMethodAttribute)Attribute.GetCustomAttribute(method,typeof(SqlCommandMethodAttribute));

Debug.Assert(commandAttribute!=null);
Debug.Assert(commandAttribute.CommandType==CommandType.StoredProcedure||
commandAttribute.CommandType==CommandType.Text);

//创建一个SqlCommand对象,同时通过指定的attribute对它进行配置。
SqlCommandcommand=newSqlCommand();
command.Connection=connection;
command.CommandType=commandAttribute.CommandType;

//获取command的文本,如果没有指定,那么使用方法的名称作为存储过程名称
if(commandAttribute.CommandText.Length==0)
{
Debug.Assert(commandAttribute.CommandType==CommandType.StoredProcedure);
command.CommandText=method.Name;
}
else
{
command.CommandText=commandAttribute.CommandText;
}

//调用GeneratorCommandParameters方法,生成command参数,同时添加一个返回值参数
GenerateCommandParameters(command,method,values);
command.Parameters.Add(ReturnValueParameterName,SqlDbType.Int).Direction
=ParameterDirection.ReturnValue;

returncommand;
}

privatestaticvoidGenerateCommandParameters(
SqlCommandcommand,MethodInfomethod,object[]values)
{

//得到所有的参数,通过循环一一进行处理。

ParameterInfo[]methodParameters=method.GetParameters();
intparamIndex=0;

foreach(ParameterInfoparamInfoinmethodParameters)
{
//忽略掉参数被标记为[NonCommandParameter]的参数

if(Attribute.IsDefined(paramInfo,typeof(NonCommandParameterAttribute)))
continue;

//获取参数的SqlParameterattribute,如果没有指定,那么就创建一个并使用它的缺省设置。
SqlParameterAttributeparamAttribute=(SqlParameterAttribute)Attribute.GetCustomAttribute(
paramInfo,typeof(SqlParameterAttribute));

if(paramAttribute==null)
paramAttribute=newSqlParameterAttribute();

//使用attribute的设置来配置一个参数对象。使用那些已经定义的参数值。如果没有定义,那么就从方法
//的参数来推断它的参数值。
SqlParametersqlParameter=newSqlParameter();
if(paramAttribute.IsNameDefined)
sqlParameter.ParameterName=paramAttribute.Name;
else
sqlParameter.ParameterName=paramInfo.Name;

if(!sqlParameter.ParameterName.StartsWith("@"))
sqlParameter.ParameterName="@"+sqlParameter.ParameterName;

if(paramAttribute.IsTypeDefined)
sqlParameter.SqlDbType=paramAttribute.SqlDbType;

if(paramAttribute.IsSizeDefined)
sqlParameter.Size=paramAttribute.Size;

if(paramAttribute.IsScaleDefined)
sqlParameter.Scale=paramAttribute.Scale;

if(paramAttribute.IsPrecisionDefined)
sqlParameter.Precision=paramAttribute.Precision;

if(paramAttribute.IsDirectionDefined)
{
sqlParameter.Direction=paramAttribute.Direction;
}
else
{
if(paramInfo.ParameterType.IsByRef)
{
sqlParameter.Direction=paramInfo.IsOut?
ParameterDirection.Output:
ParameterDirection.InputOutput;
}
else
{
sqlParameter.Direction=ParameterDirection.Input;
}
}

//检测是否提供的足够的参数对象值
Debug.Assert(paramIndex<values.Length);

//把相应的对象值赋于参数。
sqlParameter.Value=values[paramIndex];
command.Parameters.Add(sqlParameter);


paramIndex++;
}

//检测是否有多余的参数对象值
Debug.Assert(paramIndex==values.Length);
}
}
}