分享原创可复用且非侵入性代码生成工具(for .net)
入行IT十年了,这是本人第一次网上’献丑‘。迫于工作压力,花了大半年时间写了这个生成器以辅助开发。如有价值请多多给予建议,谢谢
好了,废话少说,开动!
QA.
1.为什么要用代码生成器?
当然是为了快速开发,且保证代码的一致性,便于维护。
2.代码生成器没缺点吗?
当然有缺点了,就是它不能代替人,如果鼠标一按就生成整个系统!那我们程序员是在一边喝咖啡还是背包走人?幸好代码生成器不会那么智能..
3.代码生成器生成的代码是一锤子买卖?
可以不是一锤子买卖,反复修改生成器的元数据,可以持久享受代码生成器的好处。
4.文中这个代码生成器有什么特点?
1)理论上如果熟悉这个代码生成器的原理,任何人可以定制出自己希望的常用模式代码(为什么叫模式,指个人或团队实现功能的代码编写模式/习惯性代码等等),
目前生成的代码是针对的.NET平台下的ASP.NET MVC3+ EF+WCF+Web代码。
2)非侵入性,代码可以完全定制以适应当前架构需要,而不是架构适应生成器。
3)难度系数比较高,需要掌握antlr 文法分析+基础的java控制台编程知识+winform.net.但回报可能会远远大于付出。
5.这个工具,有人在实际中用吗?
作者和所在开发团队在使用。效果非常好,大大的减少了开发成本和测试维护成本。
6.开源吗?
计划中,由于个人工作太忙,等有空闲时间进行重构整理,以免仓促而误人子弟。
0.概要介绍
设计阶段:在文本编辑器里面编辑xml模型和数据模型元数据,工具会自动校验和分析,并生成相应代码和sql。
持久阶段:1. 设计阶段生成表后,工具从数据库获取最新表/视图,可以生成相应的增删改查功能也页面等等。
2. 支持自定义参数化查询(语法采用标准sql,支持单表/多表/高级查询),自数据层到服务层,web层的生成。
3. 反向工程:支持数据库表到设计阶段的数据模型元数据的同步,使设计永不过时并复用。
4. 支持生成数据词典。
生成器窗口:
红色区域可以望文生义,不用赘述。
双击错误列表可以打开相应文件并使光标定位到错误点。
1.设计阶段
包括对xml和数据库设计的设计。
1.1 Xml的Dom代码生成
1.1.1 xml语法规则如下:
1.1.2 生成dom操作代码:
1.1.3 生成的代码
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Xml; 6 using CodeHelper.Xml.Extension; 7 using CodeHelper.Xml; 8 9 namespace CodeHelper.Workflow.Designer.Core.Config 10 { 11 12 public class WorkflowDefine 13 : DataNode 14 { 15 public WorkflowDefine 16 () 17 : base() 18 { 19 } 20 21 public WorkflowDefine 22 (XmlNode dom) 23 : base(dom) 24 { 25 } 26 27 public WorkflowDefine 28 (Document document) 29 : base(document) 30 { 31 } 32 33 public override string XML_TAG_NAME 34 { 35 get 36 { 37 return "WorkflowDefine"; 38 } 39 set 40 { 41 throw new Exception("cannot set"); 42 } 43 } 44 45 public event ProperyChanged<string> OnId_ProperyChanged; 46 public override string Id 47 { 48 get 49 { 50 if (this.Dom.Attributes["Id"] == null) 51 return default(string); 52 return this.Dom.Attributes["Id"].Value.ToT<string>(); 53 } 54 set 55 { 56 var attr = this.Dom.Attributes.OfType<XmlAttribute>() 57 .FirstOrDefault(x => x.Name == "Id"); 58 var oldValue = default(string); 59 var newValue = value; 60 if (attr == null) 61 { 62 attr = this.Dom.Attributes.Append(this.Dom.OwnerDocument.CreateAttribute("Id")); 63 } 64 else 65 { 66 oldValue = this.Dom.Attributes["Id"].Value.ToT<string>(); 67 } 68 69 if (value != null) 70 attr.Value = value.ToString(); 71 72 if (OnId_ProperyChanged != null && oldValue != newValue) 73 { 74 OnId_ProperyChanged(oldValue, newValue); 75 } 76 this.FireAnyProperyChanged("Id", oldValue, newValue); 77 } 78 } 79 public event ProperyChanged<string> OnName_ProperyChanged; 80 public string Name 81 { 82 get 83 { 84 if (this.Dom.Attributes["Name"] == null) 85 return default(string); 86 return this.Dom.Attributes["Name"].Value.ToT<string>(); 87 } 88 set 89 { 90 var attr = this.Dom.Attributes.OfType<XmlAttribute>() 91 .FirstOrDefault(x => x.Name == "Name"); 92 var oldValue = default(string); 93 var newValue = value; 94 if (attr == null) 95 { 96 attr = this.Dom.Attributes.Append(this.Dom.OwnerDocument.CreateAttribute("Name")); 97 } 98 else 99 { 100 oldValue = this.Dom.Attributes["Name"].Value.ToT<string>(); 101 } 102 103 if (value != null) 104 attr.Value = value.ToString(); 105 106 if (OnName_ProperyChanged != null && oldValue != newValue) 107 { 108 OnName_ProperyChanged(oldValue, newValue); 109 } 110 this.FireAnyProperyChanged("Name", oldValue, newValue); 111 } 112 } 113 public event ProperyChanged<string> OnDescription_ProperyChanged; 114 public string Description 115 { 116 get 117 { 118 if (this.Dom.Attributes["Description"] == null) 119 return default(string); 120 return this.Dom.Attributes["Description"].Value.ToT<string>(); 121 } 122 set 123 { 124 var attr = this.Dom.Attributes.OfType<XmlAttribute>() 125 .FirstOrDefault(x => x.Name == "Description"); 126 var oldValue = default(string); 127 var newValue = value; 128 if (attr == null) 129 { 130 attr = this.Dom.Attributes.Append(this.Dom.OwnerDocument.CreateAttribute("Description")); 131 } 132 else 133 { 134 oldValue = this.Dom.Attributes["Description"].Value.ToT<string>(); 135 } 136 137 if (value != null) 138 attr.Value = value.ToString(); 139 140 if (OnDescription_ProperyChanged != null && oldValue != newValue) 141 { 142 OnDescription_ProperyChanged(oldValue, newValue); 143 } 144 this.FireAnyProperyChanged("Description", oldValue, newValue); 145 } 146 } 147 public event ProperyChanged<string> OnVariable_ProperyChanged; 148 public string Variable 149 { 150 get 151 { 152 if (this.Dom.Attributes["Variable"] == null) 153 return default(string); 154 return this.Dom.Attributes["Variable"].Value.ToT<string>(); 155 } 156 set 157 { 158 var attr = this.Dom.Attributes.OfType<XmlAttribute>() 159 .FirstOrDefault(x => x.Name == "Variable"); 160 var oldValue = default(string); 161 var newValue = value; 162 if (attr == null) 163 { 164 attr = this.Dom.Attributes.Append(this.Dom.OwnerDocument.CreateAttribute("Variable")); 165 } 166 else 167 { 168 oldValue = this.Dom.Attributes["Variable"].Value.ToT<string>(); 169 } 170 171 if (value != null) 172 attr.Value = value.ToString(); 173 174 if (OnVariable_ProperyChanged != null && oldValue != newValue) 175 { 176 OnVariable_ProperyChanged(oldValue, newValue); 177 } 178 this.FireAnyProperyChanged("Variable", oldValue, newValue); 179 } 180 } 181 182 public FieldDef CreateFieldDef() 183 { 184 return this.Dom.CreateNode<FieldDef>(); 185 } 186 187 public NodeList<FieldDef> Fields 188 { 189 get 190 { 191 NodeList<FieldDef> fields = null; 192 XmlNode fields_node = null; 193 194 foreach (XmlNode node in this.Dom.ChildNodes) 195 { 196 if (node.Name == "Fields") 197 { 198 fields_node = node; 199 fields = new NodeList<FieldDef>(node); 200 break; 201 } 202 } 203 204 if (fields_node != null) 205 { 206 foreach (XmlNode node in fields_node.ChildNodes) 207 { 208 fields.AddChild(new FieldDef(node)); 209 } 210 } 211 else 212 { 213 fields = this.Dom.CreateNode<NodeList<FieldDef>>("Fields"); 214 215 this.AddChild(fields); 216 } 217 return fields; 218 } 219 set 220 { 221 throw new Exception("cannot set"); 222 } 223 } 224 public ClassDef CreateClassDef() 225 { 226 return this.Dom.CreateNode<ClassDef>(); 227 } 228 229 public NodeList<ClassDef> Classes 230 { 231 get 232 { 233 NodeList<ClassDef> classes = null; 234 XmlNode classes_node = null; 235 236 foreach (XmlNode node in this.Dom.ChildNodes) 237 { 238 if (node.Name == "Classes") 239 { 240 classes_node = node; 241 classes = new NodeList<ClassDef>(node); 242 break; 243 } 244 } 245 246 if (classes_node != null) 247 { 248 foreach (XmlNode node in classes_node.ChildNodes) 249 { 250 classes.AddChild(new ClassDef(node)); 251 } 252 } 253 else 254 { 255 classes = this.Dom.CreateNode<NodeList<ClassDef>>("Classes"); 256 257 this.AddChild(classes); 258 } 259 return classes; 260 } 261 set 262 { 263 throw new Exception("cannot set"); 264 } 265 } 266 public InitDef CreateInitDef() 267 { 268 return this.Dom.CreateNode<InitDef>(); 269 } 270 271 public InitDef Init 272 { 273 get 274 { 275 foreach (XmlNode node in this.Dom.ChildNodes) 276 { 277 if (node.Name == "InitDef" && 278 node.Attributes["variable"] != null && 279 node.Attributes["variable"].Value == "Init") 280 { 281 return new InitDef(node); 282 } 283 } 284 return null; 285 } 286 set 287 { 288 if (this.Init != null) 289 { 290 this.Init.RemoveSelf(); 291 } 292 293 var attr = this.Dom.OwnerDocument.CreateAttribute("variable"); 294 attr.Value = "Init"; 295 value.Dom.Attributes.Append(attr); 296 297 this.Dom.AppendChild(value.Dom); 298 } 299 } 300 public StartStateDef CreateStartStateDef() 301 { 302 return this.Dom.CreateNode<StartStateDef>(); 303 } 304 305 public StartStateDef StartState 306 { 307 get 308 { 309 foreach (XmlNode node in this.Dom.ChildNodes) 310 { 311 if (node.Name == "StartStateDef" && 312 node.Attributes["variable"] != null && 313 node.Attributes["variable"].Value == "StartState") 314 { 315 return new StartStateDef(node); 316 } 317 } 318 return null; 319 } 320 set 321 { 322 if (this.StartState != null) 323 { 324 this.StartState.RemoveSelf(); 325 } 326 327 var attr = this.Dom.OwnerDocument.CreateAttribute("variable"); 328 attr.Value = "StartState"; 329 value.Dom.Attributes.Append(attr); 330 331 this.Dom.AppendChild(value.Dom); 332 } 333 } 334 public TerminateStateDef CreateTerminateStateDef() 335 { 336 return this.Dom.CreateNode<TerminateStateDef>(); 337 } 338 339 public TerminateStateDef TerminateState 340 { 341 get 342 { 343 foreach (XmlNode node in this.Dom.ChildNodes) 344 { 345 if (node.Name == "TerminateStateDef" && 346 node.Attributes["variable"] != null && 347 node.Attributes["variable"].Value == "TerminateState") 348 { 349 return new TerminateStateDef(node); 350 } 351 } 352 return null; 353 } 354 set 355 { 356 if (this.TerminateState != null) 357 { 358 this.TerminateState.RemoveSelf(); 359 } 360 361 var attr = this.Dom.OwnerDocument.CreateAttribute("variable"); 362 attr.Value = "TerminateState"; 363 value.Dom.Attributes.Append(attr); 364 365 this.Dom.AppendChild(value.Dom); 366 } 367 } 368 public StateDef CreateStateDef() 369 { 370 return this.Dom.CreateNode<StateDef>(); 371 } 372 373 public NodeList<StateDef> States 374 { 375 get 376 { 377 NodeList<StateDef> states = null; 378 XmlNode states_node = null; 379 380 foreach (XmlNode node in this.Dom.ChildNodes) 381 { 382 if (node.Name == "States") 383 { 384 states_node = node; 385 states = new NodeList<StateDef>(node); 386 break; 387 } 388 } 389 390 if (states_node != null) 391 { 392 foreach (XmlNode node in states_node.ChildNodes) 393 { 394 states.AddChild(new StateDef(node)); 395 } 396 } 397 else 398 { 399 states = this.Dom.CreateNode<NodeList<StateDef>>("States"); 400 401 this.AddChild(states); 402 } 403 return states; 404 } 405 set 406 { 407 throw new Exception("cannot set"); 408 } 409 } 410 public ParallelDef CreateParallelDef() 411 { 412 return this.Dom.CreateNode<ParallelDef>(); 413 } 414 415 public NodeList<ParallelDef> Parallels 416 { 417 get 418 { 419 NodeList<ParallelDef> parallels = null; 420 XmlNode parallels_node = null; 421 422 foreach (XmlNode node in this.Dom.ChildNodes) 423 { 424 if (node.Name == "Parallels") 425 { 426 parallels_node = node; 427 parallels = new NodeList<ParallelDef>(node); 428 break; 429 } 430 } 431 432 if (parallels_node != null) 433 { 434 foreach (XmlNode node in parallels_node.ChildNodes) 435 { 436 parallels.AddChild(new ParallelDef(node)); 437 } 438 } 439 else 440 { 441 parallels = this.Dom.CreateNode<NodeList<ParallelDef>>("Parallels"); 442 443 this.AddChild(parallels); 444 } 445 return parallels; 446 } 447 set 448 { 449 throw new Exception("cannot set"); 450 } 451 } 452 public SubFlowStateDef CreateSubFlowStateDef() 453 { 454 return this.Dom.CreateNode<SubFlowStateDef>(); 455 } 456 457 public NodeList<SubFlowStateDef> SubFlowStates 458 { 459 get 460 { 461 NodeList<SubFlowStateDef> subFlowStates = null; 462 XmlNode subFlowStates_node = null; 463 464 foreach (XmlNode node in this.Dom.ChildNodes) 465 { 466 if (node.Name == "SubFlowStates") 467 { 468 subFlowStates_node = node; 469 subFlowStates = new NodeList<SubFlowStateDef>(node); 470 break; 471 } 472 } 473 474 if (subFlowStates_node != null) 475 { 476 foreach (XmlNode node in subFlowStates_node.ChildNodes) 477 { 478 subFlowStates.AddChild(new SubFlowStateDef(node)); 479 } 480 } 481 else 482 { 483 subFlowStates = this.Dom.CreateNode<NodeList<SubFlowStateDef>>("SubFlowStates"); 484 485 this.AddChild(subFlowStates); 486 } 487 return subFlowStates; 488 } 489 set 490 { 491 throw new Exception("cannot set"); 492 } 493 } 494 } 495 496 public class StartStateDef 497 : DataNode 498 { 499 public StartStateDef 500 () 501 : base() 502 { 503 } 504 505 public StartStateDef 506 (XmlNode dom) 507 : base(dom) 508 { 509 } 510 511 public StartStateDef 512 (Document document) 513 : base(document) 514 { 515 } 516 517 public override string XML_TAG_NAME 518 { 519 get 520 { 521 return "StartStateDef"; 522 } 523 set 524 { 525 throw new Exception("cannot set"); 526 } 527 } 528 529 public event ProperyChanged<string> OnId_ProperyChanged; 530 public override string Id 531 { 532 get 533 { 534 if (this.Dom.Attributes["Id"] == null) 535 return default(string); 536 return this.Dom.Attributes["Id"].Value.ToT<string>(); 537 } 538 set 539 { 540 var attr = this.Dom.Attributes.OfType<XmlAttribute>() 541 .FirstOrDefault(x => x.Name == "Id"); 542 var oldValue = default(string); 543 var newValue = value; 544 if (attr == null) 545 { 546 attr = this.Dom.Attributes.Append(this.Dom.OwnerDocument.CreateAttribute("Id")); 547 } 548 else 549 { 550 oldValue = this.Dom.Attributes["Id"].Value.ToT<string>(); 551 } 552 553 if (value != null) 554 attr.Value = value.ToString(); 555 556 if (OnId_ProperyChanged != null && oldValue != newValue) 557 { 558 OnId_ProperyChanged(oldValue, newValue); 559 } 560 this.FireAnyProperyChanged("Id", oldValue, newValue); 561 } 562 } 563 public event ProperyChanged<string> OnName_ProperyChanged; 564 public string Name 565 { 566 get 567 { 568 if (this.Dom.Attributes["Name"] == null) 569 return default(string); 570 return this.Dom.Attributes["Name"].Value.ToT<string>(); 571 } 572 set 573 { 574 var attr = this.Dom.Attributes.OfType<XmlAttribute>() 575 .FirstOrDefault(x => x.Name == "Name"); 576 var oldValue = default(string); 577 var newValue = value; 578 if (attr == null) 579 { 580 attr = this.Dom.Attributes.Append(this.Dom.OwnerDocument.CreateAttribute("Name")); 581 } 582 else 583 { 584 oldValue = this.Dom.Attributes["Name"].Value.ToT<string>(); 585 } 586 587 if (value != null) 588 attr.Value = value.ToString(); 589 590 if (OnName_ProperyChanged != null && oldValue != newValue) 591 { 592 OnName_ProperyChanged(oldValue, newValue); 593 } 594 this.FireAnyProperyChanged("Name", oldValue, newValue); 595 } 596 } 597 598 } 599 600 //此处省略3000行... 601 }
1.2 数据表及关系设计
1.2.1 数据语法如下:
1.2.2 生成数据库sql
1.2.3 生成的sql
1 IF OBJECT_ID(N'People',N'U') IS NOT NULL 2 DROP TABLE [dbo].[People]; 3 CREATE TABLE [dbo].[People]( 4 [Id] int NOT NULL, 5 [Name] nvarchar(200) , 6 [UserId] int , 7 [SchoolId] int , 8 [Status] int , 9 CONSTRAINT [PK_People] PRIMARY KEY CLUSTERED 10 ( 11 [Id] ASC 12 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF 13 , ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 14 ) ON [PRIMARY] 15 16 GO
1.3 持久化阶段
1.3.1 新建连接串
1.3.2 刷新链接,获取数据库所有的表和视图信息
刷新结果:
1.3.3 弹出生成操作
1.3.4 实体层生成
1.3.4.1 生成的EF实体类:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using Domain.Entities; 6 using Domain.AggregateRoot; 7 8 namespace AAA 9 { 10 11 public class People : Entity, IAggregateRoot 12 { 13 public People() 14 { 15 } 16 public People(System.Int32 id) 17 : base(id) 18 { 19 } 20 /// <summary> 21 /// 22 /// </summary> 23 public DateTime? CreateTime 24 { get; set; } 25 26 /// <summary> 27 /// 28 /// </summary> 29 public String Name 30 { get; set; } 31 32 /// <summary> 33 /// 34 /// </summary> 35 public Int32? SchoolId 36 { get; set; } 37 38 /// <summary> 39 /// 40 /// </summary> 41 public Int32? Status 42 { get; set; } 43 44 /// <summary> 45 /// 46 /// </summary> 47 public DateTime? UpdateTime 48 { get; set; } 49 50 /// <summary> 51 /// 52 /// </summary> 53 public Int32? UserId 54 { get; set; } 55 56 /// <summary> 57 /// 58 /// </summary> 59 public virtual User User 60 { get; set; } 61 62 /// <summary> 63 /// 64 /// </summary> 65 public virtual School School 66 { get; set; } 67 68 public void AssignFrom(People other) 69 { 70 this.CreateTime = other.CreateTime; 71 this.Name = other.Name; 72 this.SchoolId = other.SchoolId; 73 this.Status = other.Status; 74 this.UpdateTime = other.UpdateTime; 75 this.UserId = other.UserId; 76 } 77 } 78 }
1.3.4.2 生成的EF映射类:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using Domain.Repository; 6 7 namespace AAA 8 { 9 10 public interface IPeopleRepository : IRepository<People>, IDisposable 11 { 12 List<People> GetList(List<Guid> id_list); 13 } 14 }
弹出生成Repository操作:
1.3.4.3 Repository接口代码:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using Domain.Repository; 6 7 namespace AAA 8 { 9 10 public interface IPeopleRepository : IRepository<People>, IDisposable 11 { 12 List<People> GetList(List<Guid> id_list); 13 } 14 }
1.3.4.4 Specification规约代码:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using Domain.Specification; 6 7 namespace AAA 8 { 9 10 public static class PeopleSpecification 11 { 12 public static ISpecification<People> GetList(List<Guid> id_list) 13 { 14 return new DirectSpecification<People>(x => id_list.Contains(x.Id)); 15 } 16 } 17 }
1.3.4.5 Repository实现代码:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using Data; 6 using Data.Repository; 7 8 namespace AAA 9 { 10 11 public class PeopleRepository : Repository<People>, IPeopleRepository 12 { 13 public PeopleRepository(IQueryableUnitOfWork unitOfWork) 14 : base(unitOfWork) 15 { 16 } 17 18 public List<People> GetList(List<Guid> id_list) 19 { 20 return this.GetAll(PeopleSpecification.GetList(id_list)).ToList(); 21 } 22 23 public void Dispose() 24 { 25 //throw new NotImplementedException(); 26 } 27 } 28 }
1.3.5 Service层生成
1.3.5.1 弹出生成WCF操作:
1.3.5.2 生成DTO代码:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Runtime.Serialization; 6 7 namespace AAA 8 { 9 10 [DataContract] 11 public class PeopleDto 12 { 13 /// <summary> 14 /// 15 /// </summary> 16 [DataMember] 17 public DateTime? CreateTime 18 { get; set; } 19 20 /// <summary> 21 /// 22 /// </summary> 23 [DataMember] 24 public Int32 Id 25 { get; set; } 26 27 /// <summary> 28 /// 29 /// </summary> 30 [DataMember] 31 public String Name 32 { get; set; } 33 34 /// <summary> 35 /// 36 /// </summary> 37 [DataMember] 38 public Int32? SchoolId 39 { get; set; } 40 41 /// <summary> 42 /// 43 /// </summary> 44 [DataMember] 45 public Int32? Status 46 { get; set; } 47 48 /// <summary> 49 /// 50 /// </summary> 51 [DataMember] 52 public DateTime? UpdateTime 53 { get; set; } 54 55 /// <summary> 56 /// 57 /// </summary> 58 [DataMember] 59 public Int32? UserId 60 { get; set; } 61 62 } 63 }
1.3.5.3 生成实体转DTO代码:(建议用automap替代)
1 public static PeopleDto ConvertToPeopleDto(People entity) 2 { 3 return new PeopleDto{ 4 Id = entity.Id, 5 Name = entity.Name, 6 SchoolId = entity.SchoolId, 7 Status = entity.Status, 8 UserId = entity.UserId, 9 }; 10 }
1.3.5.4 生成DTO转实体代码:(建议用automap替代)
1 public static People ConvertToPeople(PeopleDto entityDto) 2 { 3 return new People(entityDto.Id){ 4 Name = entityDto.Name, 5 SchoolId = entityDto.SchoolId, 6 Status = entityDto.Status, 7 UserId = entityDto.UserId, 8 }; 9 }
1.3.5.5 生成基本Servie代码:(基础增删改查)
1 #region App Service Interface 2 3 ReturnInfoDto AddPeople(PeopleDto peopleDto); 4 5 ReturnInfoDto UpdatePeople(PeopleDto peopleDto); 6 7 ReturnInfoDto<PeopleDto> GetPeople(Guid id); 8 9 ReturnInfoDto<List<PeopleDto>> GetPeopleList(List<Guid> id_list); 10 11 ReturnInfoDto DeletePeople(Guid id); 12 13 ReturnInfoDto DeletePeople(List<Guid> id_list); 14 15 #endregion 16 17 #region App Service Implement 18 19 public ReturnInfoDto AddPeople(PeopleDto peopleDto) 20 { 21 var rtnInfo = new ReturnInfoDto(); 22 rtnInfo.Message = string.Empty; 23 rtnInfo.IsSuccess = false; 24 try 25 { 26 using (var unitOfWork = UnitOfWorkFactory.Create(DbOption.OA)) 27 { 28 var peopleDB = new PeopleRepository(unitOfWork); 29 var people = DataConverter.ConvertToPeople(peopleDto); 30 peopleDB.Add(people); 31 unitOfWork.Commit(); 32 } 33 } 34 catch (Exception ex) 35 { 36 rtnInfo.Message = ex.Message; 37 return rtnInfo; 38 } 39 40 rtnInfo.IsSuccess = true; 41 return rtnInfo; 42 } 43 44 public ReturnInfoDto UpdatePeople(PeopleDto peopleDto) 45 { 46 var rtnInfo = new ReturnInfoDto(); 47 rtnInfo.Message = string.Empty; 48 rtnInfo.IsSuccess = false; 49 try 50 { 51 using (var unitOfWork = UnitOfWorkFactory.Create(DbOption.OA)) 52 { 53 var peopleDB = new PeopleRepository(unitOfWork); 54 var info = peopleDB.Get(peopleDto.Id); 55 if (info == null) 56 { 57 rtnInfo.Message = "the data is not in system."; 58 return rtnInfo; 59 } 60 var other = DataConverter.ConvertToPeople(peopleDto); 61 info.AssignFrom(other); 62 peopleDB.Modify(info); 63 unitOfWork.Commit(); 64 } 65 } 66 catch (Exception ex) 67 { 68 rtnInfo.Message = ex.Message; 69 return rtnInfo; 70 } 71 72 rtnInfo.IsSuccess = true; 73 return rtnInfo; 74 } 75 76 public ReturnInfoDto<PeopleDto> GetPeople(Guid id) 77 { 78 var rtnInfo = new ReturnInfoDto<PeopleDto>(); 79 rtnInfo.Message = string.Empty; 80 rtnInfo.IsSuccess = false; 81 try 82 { 83 using (var unitOfWork = UnitOfWorkFactory.Create(DbOption.OA)) 84 { 85 var peopleDB = new PeopleRepository(unitOfWork); 86 var people = peopleDB.Get(id); 87 if(people != null) 88 { 89 rtnInfo.Data = DataConverter.ConvertToPeopleDto(people); 90 } 91 } 92 } 93 catch (Exception ex) 94 { 95 rtnInfo.Message = ex.Message; 96 return rtnInfo; 97 } 98 99 rtnInfo.IsSuccess = true; 100 return rtnInfo; 101 } 102 103 public ReturnInfoDto<List<PeopleDto>> GetPeopleList(List<Guid> id_list) 104 { 105 var rtnInfo = new ReturnInfoDto<List<PeopleDto>>(); 106 rtnInfo.Message = string.Empty; 107 rtnInfo.IsSuccess = false; 108 rtnInfo.Data = new List<PeopleDto>(); 109 try 110 { 111 using (var unitOfWork = UnitOfWorkFactory.Create(DbOption.OA)) 112 { 113 var peopleDB = new PeopleRepository(unitOfWork); 114 var list = peopleDB.GetList(id_list); 115 if(list != null && list.Count > 0 ) 116 { 117 list.ForEach( x => rtnInfo.Data.Add(DataConverter.ConvertToPeopleDto(x))); 118 } 119 } 120 } 121 catch (Exception ex) 122 { 123 rtnInfo.Message = ex.Message; 124 return rtnInfo; 125 } 126 127 rtnInfo.IsSuccess = true; 128 return rtnInfo; 129 } 130 131 public ReturnInfoDto DeletePeople(Guid id) 132 { 133 var rtnInfo = new ReturnInfoDto(); 134 rtnInfo.Message = string.Empty; 135 rtnInfo.IsSuccess = false; 136 try 137 { 138 using (var unitOfWork = UnitOfWorkFactory.Create(DbOption.OA)) 139 { 140 var peopleDB = new PeopleRepository(unitOfWork); 141 var people = peopleDB.Get(id); 142 if(people == null ) 143 { 144 rtnInfo.Message = "the data is not in system."; 145 return rtnInfo; 146 } 147 //people.Available = false; 148 //peopleDB.Modify(people); 149 peopleDB.Remove(people); 150 unitOfWork.Commit(); 151 } 152 } 153 catch (Exception ex) 154 { 155 rtnInfo.Message = ex.Message; 156 return rtnInfo; 157 } 158 159 rtnInfo.IsSuccess = true; 160 return rtnInfo; 161 } 162 163 public ReturnInfoDto DeletePeople(List<Guid> id_list) 164 { 165 var rtnInfo = new ReturnInfoDto(); 166 rtnInfo.Message = string.Empty; 167 rtnInfo.IsSuccess = false; 168 try 169 { 170 using (var unitOfWork = UnitOfWorkFactory.Create(DbOption.OA)) 171 { 172 var peopleDB = new PeopleRepository(unitOfWork); 173 var people_list = peopleDB.GetList(id_list); 174 foreach (var people in people_list) 175 { 176 //people.Available = false; 177 //peopleDB.Modify(people); 178 peopleDB.Remove(people); 179 } 180 unitOfWork.Commit(); 181 } 182 } 183 catch (Exception ex) 184 { 185 rtnInfo.Message = ex.Message; 186 return rtnInfo; 187 } 188 189 rtnInfo.IsSuccess = true; 190 return rtnInfo; 191 } 192 193 #endregion 194 195 #region Distribute Service Interface 196 197 [OperationContract] 198 [WithoutAuthorization] 199 [FaultContractAttribute(typeof(UnAuthorization))] 200 ReturnInfoDto AddPeople(PeopleDto peopleDto); 201 202 [OperationContract] 203 [WithoutAuthorization] 204 [FaultContractAttribute(typeof(UnAuthorization))] 205 ReturnInfoDto UpdatePeople(PeopleDto peopleDto); 206 207 [OperationContract] 208 [WithoutAuthorization] 209 [FaultContractAttribute(typeof(UnAuthorization))] 210 ReturnInfoDto<PeopleDto> GetPeople(Guid id); 211 212 [OperationContract] 213 [WithoutAuthorization] 214 [FaultContractAttribute(typeof(UnAuthorization))] 215 ReturnInfoDto<List<PeopleDto>> GetPeopleList(List<Guid> id_list); 216 217 [OperationContract] 218 [WithoutAuthorization] 219 [FaultContractAttribute(typeof(UnAuthorization))] 220 ReturnInfoDto DeletePeople(Guid id); 221 222 [OperationContract] 223 [WithoutAuthorization] 224 [FaultContractAttribute(typeof(UnAuthorization))] 225 ReturnInfoDto DeletePeopleList(List<Guid> id_list); 226 227 #endregion 228 229 #region Distribute Service Implement 230 231 public ReturnInfoDto AddPeople(PeopleDto peopleDto) 232 { 233 return _appService.AddPeople(peopleDto); 234 } 235 236 public ReturnInfoDto UpdatePeople(PeopleDto peopleDto) 237 { 238 return _appService.UpdatePeople(peopleDto); 239 } 240 241 public ReturnInfoDto<PeopleDto> GetPeople(Guid id) 242 { 243 return _appService.GetPeople( id ); 244 } 245 246 public ReturnInfoDto<List<PeopleDto>> GetPeopleList(List<Guid> id_list) 247 { 248 return _appService.GetPeopleList( id_list ); 249 } 250 251 public ReturnInfoDto DeletePeople(Guid id) 252 { 253 return _appService.DeletePeople( id ); 254 } 255 256 public ReturnInfoDto DeletePeopleList(List<Guid> id_list) 257 { 258 return _appService.DeletePeople( id_list ); 259 } 260 261 #endregion 262 263 #region Service Layer 264 265 public ReturnInfo AddPeople(PeopleInfo peopleInfo) 266 { 267 var result = new ReturnInfo(); 268 269 try 270 { 271 var dto = DataConverter.ConvertToPeopleDto(peopleInfo); 272 var rslt = serviceClient.Invoke<ReturnInfoDto>(x => x.AddPeople(dto)); 273 result.IsSuccess = rslt.IsSuccess; 274 result.Message = rslt.Message; 275 276 } 277 catch (Exception e) 278 { 279 LogHelper.Error(e); 280 result.IsSuccess = false; 281 result.Message = "call service error"; 282 } 283 284 return result; 285 } 286 287 public ReturnInfo UpdatePeople(PeopleInfo peopleInfo) 288 { 289 var result = new ReturnInfo(); 290 291 try 292 { 293 var dto = DataConverter.ConvertToPeopleDto(peopleInfo); 294 var rslt = serviceClient.Invoke<ReturnInfoDto>(x => x.UpdatePeople(dto)); 295 result.IsSuccess = rslt.IsSuccess; 296 result.Message = rslt.Message; 297 298 } 299 catch (Exception e) 300 { 301 LogHelper.Error(e); 302 result.IsSuccess = false; 303 result.Message = "call service error"; 304 } 305 306 return result; 307 } 308 309 public ReturnInfo<PeopleInfo> GetPeople(Guid id) 310 { 311 var result = new ReturnInfo<PeopleInfo>(); 312 313 try 314 { 315 var rslt = serviceClient.Invoke<ReturnInfoDto<PeopleDto>>(x => x.GetPeople(id)); 316 result.Data = DataConverter.ConvertToPeopleInfo(rslt.Data); 317 result.IsSuccess = rslt.IsSuccess; 318 result.Message = rslt.Message; 319 320 } 321 catch (Exception e) 322 { 323 LogHelper.Error(e); 324 result.IsSuccess = false; 325 result.Message = "call service error"; 326 } 327 328 return result; 329 } 330 331 public ReturnInfo<List<PeopleInfo>> GetPeopleList(List<Guid> id_list) 332 { 333 var result = new ReturnInfo<List<PeopleInfo>>(); 334 result.Data = new List<PeopleInfo>(); 335 336 try 337 { 338 var rslt = serviceClient.Invoke<ReturnInfoDto<List<PeopleDto>>>(x => x.GetPeopleList(id_list)); 339 result.IsSuccess = rslt.IsSuccess; 340 result.Message = rslt.Message; 341 if (rslt.IsSuccess ) 342 { 343 if (rslt.Data != null && rslt.Data.Count > 0) 344 { 345 rslt.Data.ForEach(x => result.Data.Add(DataConverter.ConvertToPeopleInfo(x))); 346 } 347 } 348 } 349 catch (Exception e) 350 { 351 LogHelper.Error(e); 352 result.IsSuccess = false; 353 result.Message = "call service error"; 354 } 355 356 return result; 357 } 358 359 public ReturnInfo DeletePeople(Guid id) 360 { 361 var result = new ReturnInfo(); 362 363 try 364 { 365 var rslt = serviceClient.Invoke<ReturnInfoDto>(x => x.DeletePeople(id)); 366 result.IsSuccess = rslt.IsSuccess; 367 result.Message = rslt.Message; 368 369 } 370 catch (Exception e) 371 { 372 LogHelper.Error(e); 373 result.IsSuccess = false; 374 result.Message = "call service error"; 375 } 376 377 return result; 378 } 379 380 public ReturnInfo DeletePeople(List<Guid> id_list) 381 { 382 var result = new ReturnInfo(); 383 384 try 385 { 386 var rslt = serviceClient.Invoke<ReturnInfoDto>(x => x.DeletePeopleList(id_list)); 387 result.IsSuccess = rslt.IsSuccess; 388 result.Message = rslt.Message; 389 390 } 391 catch (Exception e) 392 { 393 LogHelper.Error(e); 394 result.IsSuccess = false; 395 result.Message = "call service error"; 396 } 397 398 return result; 399 } 400 401 #endregion
1.3.5.6 生成CCFlowService:此处省略(比较私有)
1.3.6 Web层生成
1.3.6.1 弹出ViewMode生成操作:
1.3.6.2 生成ViewModel代码:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Runtime.Serialization; 6 7 namespace AAA 8 { 9 10 public class PeopleInfo 11 { 12 /// <summary> 13 /// 14 /// </summary> 15 public DateTime? CreateTime 16 { get; set; } 17 18 /// <summary> 19 /// 20 /// </summary> 21 public Int32 Id 22 { get; set; } 23 24 /// <summary> 25 /// 26 /// </summary> 27 public String Name 28 { get; set; } 29 30 /// <summary> 31 /// 32 /// </summary> 33 public Int32? SchoolId 34 { get; set; } 35 36 /// <summary> 37 /// 38 /// </summary> 39 public Int32? Status 40 { get; set; } 41 42 /// <summary> 43 /// 44 /// </summary> 45 public DateTime? UpdateTime 46 { get; set; } 47 48 /// <summary> 49 /// 50 /// </summary> 51 public Int32? UserId 52 { get; set; } 53 54 } 55 }
1.3.6.3 生成ViewModel转WCF DTO代码:(建议用automapper替代)
1 public static PeopleDto ConvertToPeopleDto(PeopleInfo info) 2 { 3 return new PeopleDto{ 4 Id = info.Id, 5 Name = info.Name, 6 SchoolId = info.SchoolId, 7 Status = info.Status, 8 UserId = info.UserId, 9 }; 10 }
1.3.6.4 生成WCF DTO转ViewModel代码:(建议用automapper替代)
1 public static PeopleInfo ConvertToPeopleInfo(PeopleDto dto ) 2 { 3 return new PeopleInfo(){ 4 Id = dto.Id, 5 Name = dto.Name, 6 SchoolId = dto.SchoolId, 7 Status = dto.Status, 8 UserId = dto.UserId, 9 }; 10 }
1.3.6.5 弹出生成View操作:
1.3.6.6 生成编辑页面Model代码:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Runtime.Serialization; 6 namespace AAA 7 { 8 9 public class PeopleInfo 10 { 11 /// <summary> 12 /// 13 /// </summary> 14 public DateTime? CreateTime 15 { get; set; } 16 17 /// <summary> 18 /// 19 /// </summary> 20 public Int32 Id 21 { get; set; } 22 23 /// <summary> 24 /// 25 /// </summary> 26 public String Name 27 { get; set; } 28 29 /// <summary> 30 /// 31 /// </summary> 32 public Int32? SchoolId 33 { get; set; } 34 35 /// <summary> 36 /// 37 /// </summary> 38 public Int32? Status 39 { get; set; } 40 41 /// <summary> 42 /// 43 /// </summary> 44 public DateTime? UpdateTime 45 { get; set; } 46 47 /// <summary> 48 /// 49 /// </summary> 50 public Int32? UserId 51 { get; set; } 52 53 } 54 }
1.3.6.7 生成编辑页面代码:
1 @model EditPeopleModel 2 @{ 3 Layout = "~/Views/Shared/_SimpleLayout.cshtml"; 4 5 if(this.Model.Id.HasValue){ 6 ViewBag.Title = "Edit Item"; 7 } 8 else{ 9 ViewBag.Title = "Add Item"; 10 } 11 } 12 13 @section js{ 14 <script src="../../Scripts/jquery.validate.js" type="text/javascript"></script> 15 <script language = "javascript" type="text/javascript"> 16 function OnClose(refresh) { 17 if (parent.MsgBox != undefined) { 18 19 if (refresh) { 20 if (parent.MsgBox.Callback != null) { 21 parent.MsgBox.Callback(); 22 parent.MsgBox.Callback = null; 23 } 24 } 25 parent.MsgBox.Callback = null; 26 27 parent.MsgBox.Close(); 28 29 } 30 else { 31 window.close(); 32 } 33 } 34 35 $(function () { 36 37 if (parent.MsgBox != undefined) { 38 parent.MsgBox.CancelCallback = true; 39 } 40 41 $('#btnSaveAndClose').click(function () { 42 43 $('#IsSave').val(true); 44 45 $('#editForm').submit(); 46 47 }); 48 49 $('#btnCancel').click(function () { 50 51 OnClose(); 52 53 }); 54 55 if ($('#IsSave').val() == 'True') { 56 var msg = $('#ErrorMsg').val(); 57 if (msg == '') { 58 jAlert('Save Success','Tip',function(){ 59 OnClose(true); 60 }); 61 } 62 else { 63 jAlert(msg); 64 } 65 } 66 67 $('#somecontrolId').attr('readonly','true').addClass('readonly'); 68 69 $('select').each(function(){ 70 $(this).val($(this).attr('_value')); 71 }); 72 73 var validator = $('#editForm').validate({ 74 debug: true, //调试模式取消submit的默认提交功能 75 errorClass: 'error', //默认为错误的样式类为:error 76 focusInvalid: false, 77 onkeyup: false, 78 submitHandler: function (form) { //表单提交句柄,为一回调函数,带一个参数:form 79 //alert('提交表单'); 80 form.submit(); //提交表单 81 }, 82 rules: { //定义验证规则,其中属性名为表单的name属性 83 Name:{ 84 }, 85 SchoolId:{ 86 }, 87 Status:{ 88 }, 89 UserId:{ 90 } 91 92 }, 93 94 messages: { //自定义验证消息 95 PurchasePlan: { 96 //required: 'required !', 97 //minlength: $.format('用户名至少要{0}个字符!'), 98 //remote: $.format('{0}已经被占用') 99 }, 100 }, 101 errorPlacement: function (error, element) { 102 var noHtml = '<div class="notification error" for="' + error.attr('for') + '">' + 103 "<a class=\"close\" ><img alt=\"close\" title=\"Close this notification\" src=\"/Content/images/cross_grey_small.png\"></a>" + 104 '<div>' + error.html() + '</div>' + '</div>'; 105 var notification = element.parent().find('div'); 106 if (notification.length > 0) { 107 notification.remove(); 108 } 109 element.parent().find('span').hide(); 110 $(noHtml).appendTo(element.parent()); 111 error.html(''); 112 error.appendTo(element.parent()); 113 }, 114 highlight: function (element, errorClass) { //针对验证的表单设置高亮 115 //$(element).addClass(errorClass); 116 }, 117 success: function (element) { 118 element.parent().find('span').show(); 119 element.parent().find('div.error,label.validateError').remove(); 120 }}); 121 }); 122 </script> 123 124 } 125 126 @section css{ 127 128 <style type="text/css"> 129 body 130 { 131 background: none; 132 } 133 .field 134 { 135 vertical-align: middle; 136 clear: both; 137 padding-left: 5px; 138 padding-top: 5px; 139 padding-bottom: 5px; 140 } 141 .field_name 142 { 143 width: 160px; 144 float: left; 145 padding-right: 10px; 146 padding-top: 10px; 147 margin: 0 auto; 148 } 149 .field_value 150 { 151 width: 260px; 152 float: left; 153 } 154 custom-combobox input 155 { 156 width: 120px; 157 } 158 .operation 159 { 160 margin-top: 20px; 161 padding-top: 20px; 162 clear: both; 163 } 164 input 165 { 166 width: 206px; 167 } 168 select 169 { 170 width: 220px; 171 } 172 .readonly 173 { 174 background-color: #e6e6e6; 175 } 176 </style> 177 178 } 179 180 <div class="tabmini-content"> 181 <form method="post" id="editForm" class="form" action="/xxx/EditPeopleItem"> 182 183 <input type='hidden' id='Id' name='Id' value='@Model.Id' /> 184 <input type='hidden' id='IsPostBack' name='IsPostBack' value='true' /> 185 <input type='hidden' id='IsSave' name='IsSave' value='@Model.IsSave' /> 186 <input type='hidden' id='ErrorMsg' name='ErrorMsg' value='@Model.ErrorMsg' /> 187 188 <fieldset class="ConfigArea"> 189 <div class="field"> 190 <div class="field_name"> 191 <label>Name:</label> 192 </div> 193 <div class="field_value"> 194 <input type="text" name="Name" id="Name" value="@Model.Name"/> 195 </div> 196 </div> 197 <div class="field"> 198 <div class="field_name"> 199 <label>SchoolId:</label> 200 </div> 201 <div class="field_value"> 202 <input type="text" name="SchoolId" id="SchoolId" value="@Model.SchoolId"/> 203 </div> 204 </div> 205 <div class="field"> 206 <div class="field_name"> 207 <label>Status:</label> 208 </div> 209 <div class="field_value"> 210 <input type="text" name="Status" id="Status" value="@Model.Status"/> 211 </div> 212 </div> 213 <div class="field"> 214 <div class="field_name"> 215 <label>UserId:</label> 216 </div> 217 <div class="field_value"> 218 <input type="text" name="UserId" id="UserId" value="@Model.UserId"/> 219 </div> 220 </div> 221 <div class='operation'> 222 <a class='button blue' id='btnSaveAndClose'>Save&Close</a> <a class='button blue' 223 id='btnCancel'>Cancel</a> 224 </div> 225 </fieldset> 226 </form> 227 </div>
1.3.6.8 弹出生成MVC代码操作:
1.3.6.9 生成Action代码:
1 public ActionResult EditPeople(EditPeopleModel model) 2 { 3 4 //model.UserId = Motorola.ZCH49.OaSystem.WebSite.Models.User.GetCurrentUser(this).Id; 5 model.Action(); 6 return View(model); 7 8 } 9 10 [HttpPost] 11 public ActionResult DeletePeople(Guid id) 12 { 13 var model = new ReturnInfo(); 14 15 if (id == default(Guid)) 16 { 17 model.Message = "no id"; 18 } 19 else 20 { 21 model = EditPeopleModel.DeletePeople(id); 22 } 23 return Json(model, JsonRequestBehavior.AllowGet); 24 25 } 26 27 [HttpPost] 28 public ActionResult DeletePeople(List<Guid> idList) 29 { 30 var model = new ReturnInfo(); 31 32 if (idList == null || idList.Count == 0) 33 { 34 model.Message = "no id"; 35 } 36 else 37 { 38 model = EditPeopleModel.DeletePeople(idList); 39 } 40 return Json(model, JsonRequestBehavior.AllowGet); 41 42 }
1.3.7 视图的相关操作和表操作一样
1.4 自定义查询(解决常见查询动态参数化问题)
1.4.1 创建查询集(类似文件夹/目录概念,对查询进行管理)
1.4.2 创建查询
1.4.3 编辑查询
语法和语义同标准sql,主要用于动态的参数化查询,一下为一个常用查询的参数化(分页,各字段的排序,参数提取)
实例代码主要是EF查相关,其他的代码生成省略。
1.4.3.1 生成的查询条件类:
1 using System; 2 using System.Collections.Generic; 3 4 namespace xxx 5 { 6 public class People_Query_Condition 7 { 8 public enum OrderByType 9 { 10 CreateTime_Asc, 11 CreateTime_Desc, 12 Id_Asc, 13 Id_Desc, 14 Name_Asc, 15 Name_Desc, 16 SchoolId_Asc, 17 SchoolId_Desc, 18 Status_Asc, 19 Status_Desc, 20 UpdateTime_Asc, 21 UpdateTime_Desc, 22 UserId_Asc, 23 UserId_Desc, 24 25 } 26 27 public OrderByType? OrderBy { get; set; } 28 29 public DateTime? CreateTime_Begin 30 { get; set; } 31 32 public DateTime? CreateTime_End 33 { get; set; } 34 35 public int? Id 36 { get; set; } 37 38 public List<int> Ids 39 { get; set; } 40 41 public string Name 42 { get; set; } 43 44 public int? SchoolId 45 { get; set; } 46 47 public int? Status 48 { get; set; } 49 50 public int? UserId 51 { get; set; } 52 53 54 public int PageIndex { get; set; } 55 public int PageSize { get; set; } 56 public int RecordCount { get; set; } 57 public People_Query_Condition() 58 { 59 this.Ids = new List<int>(); 60 } 61 } 62 }
1.4.3.2 生成的查询DTO类:
1 using System; 2 using System.Collections.Generic; 3 using System.Runtime.Serialization; 4 5 namespace xxx 6 { 7 [DataContract] 8 public class People_Query_ConditionDto 9 { 10 [DataContract] 11 public enum OrderByType 12 { 13 [EnumMember] 14 CreateTime_Asc, 15 [EnumMember] 16 CreateTime_Desc, 17 [EnumMember] 18 Id_Asc, 19 [EnumMember] 20 Id_Desc, 21 [EnumMember] 22 Name_Asc, 23 [EnumMember] 24 Name_Desc, 25 [EnumMember] 26 SchoolId_Asc, 27 [EnumMember] 28 SchoolId_Desc, 29 [EnumMember] 30 Status_Asc, 31 [EnumMember] 32 Status_Desc, 33 [EnumMember] 34 UpdateTime_Asc, 35 [EnumMember] 36 UpdateTime_Desc, 37 [EnumMember] 38 UserId_Asc, 39 [EnumMember] 40 UserId_Desc, 41 42 } 43 44 [DataMember] 45 public OrderByType? OrderBy { get; set; } 46 47 [DataMember] 48 public DateTime? CreateTime_Begin 49 { get; set; } 50 51 [DataMember] 52 public DateTime? CreateTime_End 53 { get; set; } 54 55 [DataMember] 56 public int? Id 57 { get; set; } 58 59 [DataMember] 60 public List<int> Ids 61 { get; set; } 62 63 [DataMember] 64 public string Name 65 { get; set; } 66 67 [DataMember] 68 public int? SchoolId 69 { get; set; } 70 71 [DataMember] 72 public int? Status 73 { get; set; } 74 75 [DataMember] 76 public int? UserId 77 { get; set; } 78 79 [DataMember] 80 public int PageIndex { get; set; } 81 [DataMember] 82 public int PageSize { get; set; } 83 [DataMember] 84 public int RecordCount { get; set; } 85 public People_Query_ConditionDto() 86 { 87 this.Ids = new List<int>(); 88 } 89 } 90 }
1.4.3.3 生成的EF规约代码:
1 public static ISpecification<People> People_Query(People_Query_Condition condition) 2 { 3 ISpecification<People> id_spec = null; 4 if (!condition.Id.HasValue) 5 { 6 id_spec = new DirectSpecification<People>(x=> true); 7 } 8 else{ 9 id_spec = new DirectSpecification<People>(x=> 10 x.Id == condition.Id 11 ); 12 } 13 14 ISpecification<People> ids_spec = null; 15 if (condition.Ids == null || condition.Ids.Count == 0) 16 { 17 ids_spec = new DirectSpecification<People>(x=> true); 18 } 19 else{ 20 } 21 22 ISpecification<People> name_spec = null; 23 if (string.IsNullOrWhiteSpace(condition.Name)) 24 { 25 name_spec = new DirectSpecification<People>(x=> true); 26 } 27 else{ 28 name_spec = new DirectSpecification<People>(x=> 29 x.Name.Contains(condition.Name) 30 ); 31 } 32 33 ISpecification<People> schoolId_spec = null; 34 if (!condition.SchoolId.HasValue) 35 { 36 schoolId_spec = new DirectSpecification<People>(x=> true); 37 } 38 else{ 39 schoolId_spec = new DirectSpecification<People>(x=> 40 x.SchoolId == condition.SchoolId 41 ); 42 } 43 44 ISpecification<People> status_spec = null; 45 if (!condition.Status.HasValue) 46 { 47 status_spec = new DirectSpecification<People>(x=> true); 48 } 49 else{ 50 status_spec = new DirectSpecification<People>(x=> 51 x.Status == condition.Status 52 ); 53 } 54 55 ISpecification<People> userId_spec = null; 56 if (!condition.UserId.HasValue) 57 { 58 userId_spec = new DirectSpecification<People>(x=> true); 59 } 60 else{ 61 userId_spec = new DirectSpecification<People>(x=> 62 x.UserId == condition.UserId 63 ); 64 } 65 66 ISpecification<People> createTime_Begin_spec = null; 67 if (!condition.CreateTime_Begin.HasValue) 68 { 69 createTime_Begin_spec = new DirectSpecification<People>(x=> true); 70 } 71 else{ 72 createTime_Begin_spec = new DirectSpecification<People>(x=> 73 x.CreateTime >= condition.CreateTime_Begin 74 ); 75 } 76 77 ISpecification<People> createTime_End_spec = null; 78 if (!condition.CreateTime_End.HasValue) 79 { 80 createTime_End_spec = new DirectSpecification<People>(x=> true); 81 } 82 else{ 83 createTime_End_spec = new DirectSpecification<People>(x=> 84 x.CreateTime <= condition.CreateTime_End 85 ); 86 } 87 88 var name_spec = new DirectSpecification<People>(x=> 89 (x.Name??"") != "" 90 ); 91 92 ISpecification<People> id_ids = new AndSpecification<People>(id_spec,ids_spec); 93 ISpecification<People> id_ids_name = new AndSpecification<People>(id_ids,name_spec); 94 ISpecification<People> id_ids_name_schoolId = new AndSpecification<People>(id_ids_name,schoolId_spec); 95 ISpecification<People> id_ids_name_schoolId_status = new AndSpecification<People>(id_ids_name_schoolId,status_spec); 96 ISpecification<People> id_ids_name_schoolId_status_userId = new AndSpecification<People>(id_ids_name_schoolId_status,userId_spec); 97 ISpecification<People> id_ids_name_schoolId_status_userId_createTime_Begin = new AndSpecification<People>(id_ids_name_schoolId_status_userId,createTime_Begin_spec); 98 ISpecification<People> id_ids_name_schoolId_status_userId_createTime_Begin_createTime_End = new AndSpecification<People>(id_ids_name_schoolId_status_userId_createTime_Begin,createTime_End_spec); 99 ISpecification<People> id_ids_name_schoolId_status_userId_createTime_Begin_createTime_End_name = new AndSpecification<People>(id_ids_name_schoolId_status_userId_createTime_Begin_createTime_End,name_spec); 100 return id_ids_name_schoolId_status_userId_createTime_Begin_createTime_End_name; 101 }
1.4.3.4 生成的EF存取代码:
1 public PageOfReturn<People> People_Query( People_Query_Condition condition ) 2 { 3 var data = this.GetAll( PeopleSpecification.People_Query(condition )); 4 if( condition.OrderBy.HasValue ) 5 { 6 switch(condition.OrderBy) 7 { 8 case People_Query_Condition.OrderByType.CreateTime_Asc: 9 data = data.OrderBy(x=>x.CreateTime); 10 break; 11 case People_Query_Condition.OrderByType.CreateTime_Desc: 12 data = data.OrderByDescending(x=>x.CreateTime); 13 break; 14 case People_Query_Condition.OrderByType.Id_Asc: 15 data = data.OrderBy(x=>x.Id); 16 break; 17 case People_Query_Condition.OrderByType.Id_Desc: 18 data = data.OrderByDescending(x=>x.Id); 19 break; 20 case People_Query_Condition.OrderByType.Name_Asc: 21 data = data.OrderBy(x=>x.Name); 22 break; 23 case People_Query_Condition.OrderByType.Name_Desc: 24 data = data.OrderByDescending(x=>x.Name); 25 break; 26 case People_Query_Condition.OrderByType.SchoolId_Asc: 27 data = data.OrderBy(x=>x.SchoolId); 28 break; 29 case People_Query_Condition.OrderByType.SchoolId_Desc: 30 data = data.OrderByDescending(x=>x.SchoolId); 31 break; 32 case People_Query_Condition.OrderByType.Status_Asc: 33 data = data.OrderBy(x=>x.Status); 34 break; 35 case People_Query_Condition.OrderByType.Status_Desc: 36 data = data.OrderByDescending(x=>x.Status); 37 break; 38 case People_Query_Condition.OrderByType.UpdateTime_Asc: 39 data = data.OrderBy(x=>x.UpdateTime); 40 break; 41 case People_Query_Condition.OrderByType.UpdateTime_Desc: 42 data = data.OrderByDescending(x=>x.UpdateTime); 43 break; 44 case People_Query_Condition.OrderByType.UserId_Asc: 45 data = data.OrderBy(x=>x.UserId); 46 break; 47 case People_Query_Condition.OrderByType.UserId_Desc: 48 data = data.OrderByDescending(x=>x.UserId); 49 break; 50 default: 51 break; 52 } 53 } 54 var result = new PageOfReturn<People>(); 55 result.RecordCount = data.Count(); 56 result.PageIndex = condition.PageIndex; 57 result.PageSize = condition.PageSize; 58 result.PageRecords = data.Skip(condition.PageSize * (condition.PageIndex - 1)).Take(condition.PageSize).ToList(); 59 return result; 60 }
1.4.3.5 其他层如Service,Web层。基本上代码少量改动一下就可以实现一个列表页面。实例代码省略
1.4.4 多表查询
1.4.4.1 生成的查询条件类:
1 using System; 2 using System.Collections.Generic; 3 4 namespace xxx 5 { 6 public class GetPeopleInfo_Condition 7 { 8 public string SchoolName 9 { get; set; } 10 11 public int? Status 12 { get; set; } 13 14 15 public GetPeopleInfo_Condition() 16 { 17 } 18 } 19 }
1.4.4.2 生成的查询条件DTO类:
1 using System; 2 using System.Collections.Generic; 3 using System.Runtime.Serialization; 4 5 namespace xxx 6 { 7 [DataContract] 8 public class GetPeopleInfo_ConditionDto 9 { 10 [DataMember] 11 public string SchoolName 12 { get; set; } 13 14 [DataMember] 15 public int? Status 16 { get; set; } 17 18 public GetPeopleInfo_ConditionDto() 19 { 20 } 21 } 22 }
1.4.4.3 生成的结果类:
1 using System; 2 using System.Linq; 3 using System.Data; 4 using System.Collections.Generic; 5 6 namespace xxx 7 { 8 public class PeopleInfo 9 { 10 public DateTime? CreateTime 11 { get; set; } 12 13 public int Id 14 { get; set; } 15 16 public string Name 17 { get; set; } 18 19 public int? SchoolId 20 { get; set; } 21 22 public int? Status 23 { get; set; } 24 25 public DateTime? UpdateTime 26 { get; set; } 27 28 public int? UserId 29 { get; set; } 30 31 public string SchoolName//来自表 School 32 { get; set; } 33 34 public string UserEmail //来自表 C_Users 35 { get; set; } 36 37 } 38 }
1.4.4.4 生成的EF代码(多表关联不再需要规约):
1 public List<PeopleInfo> GetPeopleInfo( GetPeopleInfo_Condition condition ) 2 { 3 using (var unitOfWork = UnitOfWorkFactory.Create(DbOption.OA)) 4 { 5 var p_q = ctx.Set<People>().AsQueryable(); 6 if(condition.Status != null ) 7 { 8 p_q = p_q.Where(x=>x.Status == condition.Status); 9 } 10 11 var s_q = ctx.Set<School>().AsQueryable(); 12 if(condition.SchoolName != null ) 13 { 14 s_q = s_q.Where(x=>x.Name == condition.SchoolName); 15 } 16 17 var u_q = ctx.Set<User>().AsQueryable(); 18 var q = p_q; 19 20 var q_1 = q.GroupJoin(s_q,p=>p.SchoolId,s=>s.Id, 21 (p,s)=>new { p,s = s.DefaultIfEmpty() }) 22 .SelectMany(item=>item.s.Select(s=> new {item.p,s})); 23 24 var q_2 = q_1.GroupJoin(u_q,p=>p.p.UserId,u=>u.UserId, 25 (p,u)=>new { p,u = u.DefaultIfEmpty() }) 26 .SelectMany(item=>item.u.Select(u=> new {item.p.p,item.p.s,u})); 27 28 var q_final = q_2.Where(x=> 29 true); 30 31 var list = q_final.Select(x=>new PeopleInfo(){ 32 SchoolId = x.p.SchoolId, 33 Name = x.p.Name, 34 CreateTime = x.p.CreateTime, 35 UpdateTime = x.p.UpdateTime, 36 Id = x.p.Id, 37 Status = x.p.Status, 38 UserId = x.p.UserId, 39 SchoolName = x.SchoolName, 40 UserEmail = x.UserEmail, 41 }); 42 return list.ToList(); 43 } 44 }
1.4.5 高级查询
1.4.5.1 分组查询
1.4.5.2 选项查询
1.4.5.2.1 {'op','all'} 一个字段产生多个查询条件
1.4.5.2.2 对条件查询进行条件:在某些参数非空下区域内参数才有效
写这么多,感觉需要控制篇幅,查询告一段落~
1.5 反向工程(持久阶段元数据更新设计阶段元数据)
使设计永不过期
----------->
1.6 生成数据词典
----------->
终于码完了。
2. 总结:
生成器基本上涉及了数据系统资源管理的方方面面(数据操作,应用层,服务层,展现层),能节约大量的开发时间。使工程师更注重业务知识,
举例来说,用来这套开发工具后,我们团队加班变得非常少,项目进度和预期的基本吻合。拙笔仓促,如有笔误和不妥请谅解,希望听到大家的意见和建议,thanks。