温馨提示:代码在线浏览功能只能做为源码浏览参考,如果想更进一步了解该代码请下载:AfritxiaWebTest2.0源码
当前文件:
AfritxiaWebTest20/Net.AfritXia.Data/EntityPropertyPutterMaker.cs[17K,2009-6-12 11:31:34],打开代码结构图
AfritxiaWebTest20/Net.AfritXia.Data/EntityPropertyPutterMaker.cs[17K,2009-6-12 11:31:34],打开代码结构图1#undef _Debug // 用于调试 2
3
/* 4
* EntityPropertyPutterMaker.cs @Microsoft Visual Studio 2008 <.NET Framework 2.0 (or Higher)> 5
* AfritXia, Web@ZhouLang.Net 6
* 2008/6/30 7
* 8
* Copyright(c) http://www.Bincess.CN/ 9
* 10
*/ 11
12
using System; 13
using System.CodeDom; 14
using System.Collections.Specialized; 15
using System.CodeDom.Compiler; 16
using System.Data.Common; 17
#if _Debug 18
using System.IO; 19
#endif 20
using System.Reflection; 21
22
using Microsoft.CSharp; 23
24
using Net.AfritXia.Data.Mapping; 25
26
namespace Net.AfritXia.Data 27
{ 28
/// <summary> 29
/// 构建实体属性设置器 30
/// </summary> 31
internal sealed class EntityPropertyPutterMaker 32
{ 33
// 默认名称空间 34
private const string DefaultNamespace = "Net.AfritXia.Data._AutoCode"; 35
// QuicklyPutter 类名称 36
private const string QuicklyPutterClassName = "QuicklyPutter"; 37
38
// 包含调试信息 39
private bool m_includeDebugInfo = false; 40
41
类构造器 49
50
/// <summary> 51
/// 设置或获取是否包含调试信息 52
/// </summary> 53
public bool IncludeDebugInformation 54
{ 55
set 56
{ 57
this.m_includeDebugInfo = value; 58
} 59
60
get 61
{ 62
return this.m_includeDebugInfo; 63
} 64
} 65
66
/// <summary> 67
/// 构建实体属性设置器 68
/// </summary> 69
/// <typeparam name="T">实体类型模版</typeparam> 70
/// <returns></returns> 71
public IEntityPropertyPutter<T> Make<T>() where T : class 72
{ 73
// 创建一个可编译的单元 74
CodeCompileUnit compileUnit = this.MakeCompileUnit(); 75
// 创建名称空间 76
CodeNamespace namespace_code = this.MakeNamespace(); 77
// 定义类 78
CodeTypeDeclaration class_code = this.MakeClass<T>(); 79
// 创建 PutEntityProperties 方法 80
CodeMemberMethod method_code = this.MakeMethod<T>(); 81
82
// 添加方法到类 83
class_code.Members.Add(method_code); 84
// 添加类到名称空间 85
namespace_code.Types.Add(class_code); 86
// 添加名称空间到编译单元 87
compileUnit.Namespaces.Add(namespace_code); 88
89
// 创建 C# 编译器 90
CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp"); 91
// 创建编译参数 92
CompilerParameters options = new CompilerParameters(); 93
94
// 添加对 System.dll 的引用 95
options.ReferencedAssemblies.Add("System.dll"); 96
// 添加对 System.Data.dll 的引用 97
options.ReferencedAssemblies.Add("System.Data.dll"); 98
// 添加对该项目的引用 99
options.ReferencedAssemblies.Add(this.GetType().Assembly.Location); 100
// 添加对实体项目的引用 101
options.ReferencedAssemblies.Add(typeof(T).Assembly.Location); 102
// 只在内存中编译 103
options.GenerateInMemory = true; 104
105
#if _Debug 106
string srcFilePath = null; 107
108
srcFilePath = @"C:\{0}_{1}.cs"; 109
srcFilePath = String.Format(srcFilePath, typeof(T).Name, QuicklyPutterClassName); 110
111
// 源文件输出流 112
StreamWriter srcOutput = new StreamWriter(srcFilePath, false); 113
// 写出源文件 114
provider.GenerateCodeFromCompileUnit(compileUnit, srcOutput, new CodeGeneratorOptions()); 115
116
srcOutput.Flush(); 117
srcOutput.Close(); 118
#endif 119
120
// 编译并获取编译结果 121
CompilerResults compileResult = provider.CompileAssemblyFromDom(options, compileUnit); 122
123
// 编译失败则抛出异常 124
if (compileResult.NativeCompilerReturnValue != 0) 125
throw new Exception("编译失败 ( Compile Failed )"); 126
127
// 创建设置器 128
object putter = compileResult.CompiledAssembly.CreateInstance(DefaultNamespace + "." + QuicklyPutterClassName); 129
130
return (IEntityPropertyPutter<T>)putter; 131
} 132
133
/// <summary> 134
/// 构建可编译单元 135
/// </summary> 136
/// <returns></returns> 137
private CodeCompileUnit MakeCompileUnit() 138
{ 139
// 创建一个可编译的单元 140
return new CodeCompileUnit(); 141
} 142
143
/// <summary> 144
/// 构建名称空间 145
/// </summary> 146
/// <returns></returns> 147
private CodeNamespace MakeNamespace() 148
{ 149
// 创建名称空间 150
return new CodeNamespace(DefaultNamespace); 151
} 152
153
/// <summary> 154
/// 构建 QuicklyPutter 类 155
/// </summary> 156
/// <returns></returns> 157
private CodeTypeDeclaration MakeClass<T>() where T : class 158
{ 159
// 定义 QuicklyPutter 类 160
CodeTypeDeclaration class_code = new CodeTypeDeclaration(QuicklyPutterClassName); 161
162
// 令该类实现 IEntityPropertyPutter<T> 接口 163
class_code.BaseTypes.Add(typeof(IEntityPropertyPutter<T>)); 164
165
// 添加 EntityTypeName 属性 166
class_code = this.MakeEntityTypeNameProperty<T>(class_code); 167
// 添加 CurrentPropName 属性 168
class_code = this.MakeCurrentPropNameProperty(class_code); 169
// 添加 CurrentDBColName 属性 170
class_code = this.MakeCurrentDBColNameProperty(class_code); 171
172
return class_code; 173
} 174
175
/// <summary> 176
/// 构建 EntityTypeName 属性 177
/// </summary> 178
/// <typeparam name="T">实体类型模版</typeparam> 179
/// <param name="targetClass">目标代码</param> 180
/// <returns></returns> 181
private CodeTypeDeclaration MakeEntityTypeNameProperty<T>(CodeTypeDeclaration targetClass) where T : class 182
{ 183
if (targetClass == null) 184
throw new ArgumentNullException("targetClass"); 185
186
/* 187
* 以下代码将生成 188
* 189
* public string EntityTypeName 190
* { 191
* get 192
* { 193
* return 实体类型名称字符串 194
* } 195
* } 196
* 197
* 198
*/ 199
200
// EntityTypeName 属性 201
CodeMemberProperty entityTypeNameProp_code = null; 202
203
// 创建属性 204
entityTypeNameProp_code = new CodeMemberProperty(); 205
// 定义为公共属性 206
entityTypeNameProp_code.Attributes = MemberAttributes.Public; 207
// 返回字符串类型 208
entityTypeNameProp_code.Type = new CodeTypeReference(typeof(string)); 209
// 属性名称 210
entityTypeNameProp_code.Name = "EntityTypeName"; 211
// 返回语句 212
entityTypeNameProp_code.GetStatements.Add( 213
new CodeMethodReturnStatement(new CodePrimitiveExpression(typeof(T).Name))); 214
215
// 添加属性到类 216
targetClass.Members.Add(entityTypeNameProp_code); 217
218
return targetClass; 219
} 220
221
/// <summary> 222
/// 构建 CurrentPropName 属性 223
/// </summary> 224
/// <param name="targetClass">目标类代码</param> 225
/// <returns></returns> 226
private CodeTypeDeclaration MakeCurrentPropNameProperty(CodeTypeDeclaration targetClass) 227
{ 228
if (targetClass == null) 229
throw new ArgumentNullException("targetClass"); 230
231
/* 232
* 以下代码将生成 233
* 234
* private string m_currPropName; 235
* 236
* public string CurrentPropName 237
* { 238
* get 239
* { 240
* return this.m_currPropName; 241
* } 242
* } 243
* 244
*/ 245
246
// 变量名称 247
const string VaribleName = "m_currPropName"; 248
249
// m_currPropName 250
CodeMemberField m_currPropName_code = null; 251
252
// 创建字段 253
m_currPropName_code = new CodeMemberField(); 254
// 定义为私有成员 255
m_currPropName_code.Attributes = MemberAttributes.Private; 256
// 创建变量 257
m_currPropName_code = new CodeMemberField(typeof(string), VaribleName); 258
259
// 添加成员到类 260
targetClass.Members.Add(m_currPropName_code); 261
262
// CurrentPropName 263
CodeMemberProperty currPropName_code = null; 264
265
// 创建属性 266
currPropName_code = new CodeMemberProperty(); 267
// 定义为公共属性 268
currPropName_code.Attributes = MemberAttributes.Public; 269
// 返回字符串类型 270
currPropName_code.Type = new CodeTypeReference(typeof(string)); 271
// 属性名称 272
currPropName_code.Name = "CurrentPropName"; 273
// get 返回语句 274
currPropName_code.GetStatements.Add( 275
new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), VaribleName))); 276
277
// 添加属性到类 278
targetClass.Members.Add(currPropName_code); 279
280
return targetClass; 281
} 282
283
/// <summary> 284
/// 构建 CurrentDBColName 属性 285
/// </summary> 286
/// <param name="targetClass">父级类</param> 287
/// <returns></returns> 288
private CodeTypeDeclaration MakeCurrentDBColNameProperty(CodeTypeDeclaration targetClass) 289
{ 290
if (targetClass == null) 291
throw new ArgumentNullException("targetClass"); 292
293
/* 294
* 以下代码将生成 295
* 296
* private string m_currDBColName; 297
* 298
* public string CurrentDBColName 299
* { 300
* get 301
* { 302
* return this.m_currDBColName; 303
* } 304
* } 305
* 306
*/ 307
308
// 变量名称 309
const string VaribleName = "m_currDBColName"; 310
// m_currDBColName 311
CodeMemberField m_currDBColName_code = null; 312
313
// 创建字段 314
m_currDBColName_code = new CodeMemberField(); 315
// 定义为私有成员 316
m_currDBColName_code.Attributes = MemberAttributes.Private; 317
// 创建变量 318
m_currDBColName_code = new CodeMemberField(typeof(string), VaribleName); 319
320
// 添加成员到类 321
targetClass.Members.Add(m_currDBColName_code); 322
323
// CurrentDBColName 324
CodeMemberProperty currDBCol_code = null; 325
326
// 创建属性 327
currDBCol_code = new CodeMemberProperty(); 328
// 定义为公共属性 329
currDBCol_code.Attributes = MemberAttributes.Public; 330
// 返回字符串类型 331
currDBCol_code.Type = new CodeTypeReference(typeof(string)); 332
// 属性名称 333
currDBCol_code.Name = "CurrentDBColName"; 334
// get 返回语句 335
currDBCol_code.GetStatements.Add( 336
new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_currDBColName"))); 337
338
// 添加属性到类 339
targetClass.Members.Add(currDBCol_code); 340
341
return targetClass; 342
} 343
344
/// <summary> 345
/// 构建 PutEntityProperties 方法 346
/// </summary> 347
/// <typeparam name="T"></typeparam> 348
/// <param name="fromEntity"></param> 349
/// <returns></returns> 350
private CodeMemberMethod MakeMethod<T>() where T : class 351
{ 352
// PutObjectProperties 方法 353
CodeMemberMethod method_code = null; 354
355
// 创建方法 356
method_code = new CodeMemberMethod(); 357
// 定义为公共方法 358
method_code.Attributes = MemberAttributes.Public; 359
// 返回类型 360
method_code.ReturnType = new CodeTypeReference(typeof(void)); 361
// 方法名称 362
method_code.Name = "PutEntityProperties"; 363
// 添加参数 entity 364
method_code.Parameters.Add(new CodeParameterDeclarationExpression(typeof(T), "entity")); 365
// 添加参数 dr 366
method_code.Parameters.Add(new CodeParameterDeclarationExpression(typeof(DbDataReader), "dr")); 367
368
// 获取实体类型 369
Type objType = typeof(T); 370
371
// 获取 DataTable 属性标记 372
object[] tabAttrList = objType.GetCustomAttributes(typeof(DataTableAttribute), false); 373
374
if (tabAttrList == null || tabAttrList.Length <= 0) 375
{ 376
throw new MappingException( 377
String.Format(@"类 {0} 未标记 DataTable 属性 ( Unlabeled [DataTable] Attribute On Class {0} )", objType.Name)); 378
} 379
380
// 获取属性信息 381
PropertyInfo[] propInfoList = objType.GetProperties(); 382
383
if (propInfoList == null || propInfoList.Length <= 0) 384
return null; 385
386
foreach (PropertyInfo propInfo in propInfoList) 387
{ 388
object[] colAttrList = propInfo.GetCustomAttributes(typeof(DataColumnAttribute), false); 389
390
// 未标记 DataColumn 属性 391
if (colAttrList == null || colAttrList.Length <= 0) 392
continue; 393
394
// 获取数据列属性 395
DataColumnAttribute colAttr = colAttrList[0] as DataColumnAttribute; 396
397
// 创建方法内容 398
method_code = this.MakeMethodContent(method_code, propInfo, colAttr, this.IncludeDebugInformation); 399
} 400
401
return method_code; 402
} 403
404
/// <summary> 405
/// 构建 PutEntityProperties 方法内容 406
/// </summary> 407
/// <param name="targetMethod"></param> 408
/// <param name="prop"></param> 409
/// <param name="attr"></param> 410
/// <param name="includeDebugInfo"></param> 411
/// <returns></returns> 412
private CodeMemberMethod MakeMethodContent(CodeMemberMethod targetMethod, PropertyInfo prop, DataColumnAttribute attr, bool includeDebugInfo) 413
{ 414
if (targetMethod == null) 415
throw new ArgumentNullException("targetMethod"); 416
417
if (attr == null) 418
throw new ArgumentNullException("attr"); 419
420
// 实体变量名称 entity 421
string varEntityName = targetMethod.Parameters[0].Name; 422
// 数据源变量名称 dr 423
string varDrName = targetMethod.Parameters[1].Name; 424
425
// entity 属性名称 426
string varEntityPropName = String.Format(@"{0}.{1}", varEntityName, prop.Name); 427
// dr 属性名称 428
string varDrPropName = String.Format(@"{0}[""{1}""]", varDrName, attr.Name); 429
430
// 创建变量 431
CodeVariableReferenceExpression entityProp_code = new CodeVariableReferenceExpression(varEntityPropName); 432
// 创建值 433
CodeVariableReferenceExpression dr_code = new CodeVariableReferenceExpression(varDrPropName); 434
435
// 包含调试信息 436
if (includeDebugInfo) 437
{ 438
// this.m_currPropName = entity.Prop 439
targetMethod.Statements.Add(new CodeAssignStatement( 440
new CodeVariableReferenceExpression("this.m_currPropName"), 441
new CodePrimitiveExpression(prop.Name))); 442
443
// this.m_currDBColName = attributeName 444
targetMethod.Statements.Add(new CodeAssignStatement( 445
new CodeVariableReferenceExpression("this.m_currDBColName"), 446
new CodePrimitiveExpression(attr.Name))); 447
} 448
449
if (attr.IsNullable) 450
{ 451
/* 452
* 以下代码生成的是条件判断代码 453
* 454
* if (dr["..."] != DBNull.Value) { 455
* entity.Prop = dr["..."]; 456
* } 457
* 458
*/ 459
460
CodeConditionStatement if_code = new CodeConditionStatement(); 461
462
// if (dr["..."] != DBNull.Value) 463
if_code.Condition = new CodeBinaryOperatorExpression( 464
new CodeVariableReferenceExpression(varDrPropName), 465
CodeBinaryOperatorType.IdentityInequality, 466
new CodeVariableReferenceExpression("System.DBNull.Value")); 467
468
// entity.Prop = dr["..."]; 469
if_code.TrueStatements.Add(new CodeAssignStatement( 470
entityProp_code, 471
new CodeCastExpression(prop.PropertyType, dr_code))); 472
473
targetMethod.Statements.Add(if_code); 474
} 475
else 476
{ 477
// entity.Prop = dr["..."]; 478
targetMethod.Statements.Add(new CodeAssignStatement( 479
entityProp_code, 480
new CodeCastExpression(prop.PropertyType, dr_code))); 481
} 482
483
return targetMethod; 484
} 485
} 486
}





* EntityPropertyPutterMaker.cs @Microsoft Visual Studio 2008 <.NET Framework 2.0 (or Higher)>

