分享原创可复用且非侵入性代码生成工具(for .net)

时间:2023-03-09 03:05:05
分享原创可复用且非侵入性代码生成工具(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. 支持生成数据词典。

生成器窗口:

分享原创可复用且非侵入性代码生成工具(for .net)

红色区域可以望文生义,不用赘述。

双击错误列表可以打开相应文件并使光标定位到错误点

1.设计阶段

  包括对xml和数据库设计的设计。

  

  1.1 Xml的Dom代码生成

  1.1.1 xml语法规则如下:

  分享原创可复用且非侵入性代码生成工具(for .net)

1.1.2 生成dom操作代码:

分享原创可复用且非侵入性代码生成工具(for .net)

1.1.3 生成的代码

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using CodeHelper.Xml.Extension;
using CodeHelper.Xml; namespace CodeHelper.Workflow.Designer.Core.Config
{ public class WorkflowDefine
: DataNode
{
public WorkflowDefine
()
: base()
{
} public WorkflowDefine
(XmlNode dom)
: base(dom)
{
} public WorkflowDefine
(Document document)
: base(document)
{
} public override string XML_TAG_NAME
{
get
{
return "WorkflowDefine";
}
set
{
throw new Exception("cannot set");
}
} public event ProperyChanged<string> OnId_ProperyChanged;
public override string Id
{
get
{
if (this.Dom.Attributes["Id"] == null)
return default(string);
return this.Dom.Attributes["Id"].Value.ToT<string>();
}
set
{
var attr = this.Dom.Attributes.OfType<XmlAttribute>()
.FirstOrDefault(x => x.Name == "Id");
var oldValue = default(string);
var newValue = value;
if (attr == null)
{
attr = this.Dom.Attributes.Append(this.Dom.OwnerDocument.CreateAttribute("Id"));
}
else
{
oldValue = this.Dom.Attributes["Id"].Value.ToT<string>();
} if (value != null)
attr.Value = value.ToString(); if (OnId_ProperyChanged != null && oldValue != newValue)
{
OnId_ProperyChanged(oldValue, newValue);
}
this.FireAnyProperyChanged("Id", oldValue, newValue);
}
}
public event ProperyChanged<string> OnName_ProperyChanged;
public string Name
{
get
{
if (this.Dom.Attributes["Name"] == null)
return default(string);
return this.Dom.Attributes["Name"].Value.ToT<string>();
}
set
{
var attr = this.Dom.Attributes.OfType<XmlAttribute>()
.FirstOrDefault(x => x.Name == "Name");
var oldValue = default(string);
var newValue = value;
if (attr == null)
{
attr = this.Dom.Attributes.Append(this.Dom.OwnerDocument.CreateAttribute("Name"));
}
else
{
oldValue = this.Dom.Attributes["Name"].Value.ToT<string>();
} if (value != null)
attr.Value = value.ToString(); if (OnName_ProperyChanged != null && oldValue != newValue)
{
OnName_ProperyChanged(oldValue, newValue);
}
this.FireAnyProperyChanged("Name", oldValue, newValue);
}
}
public event ProperyChanged<string> OnDescription_ProperyChanged;
public string Description
{
get
{
if (this.Dom.Attributes["Description"] == null)
return default(string);
return this.Dom.Attributes["Description"].Value.ToT<string>();
}
set
{
var attr = this.Dom.Attributes.OfType<XmlAttribute>()
.FirstOrDefault(x => x.Name == "Description");
var oldValue = default(string);
var newValue = value;
if (attr == null)
{
attr = this.Dom.Attributes.Append(this.Dom.OwnerDocument.CreateAttribute("Description"));
}
else
{
oldValue = this.Dom.Attributes["Description"].Value.ToT<string>();
} if (value != null)
attr.Value = value.ToString(); if (OnDescription_ProperyChanged != null && oldValue != newValue)
{
OnDescription_ProperyChanged(oldValue, newValue);
}
this.FireAnyProperyChanged("Description", oldValue, newValue);
}
}
public event ProperyChanged<string> OnVariable_ProperyChanged;
public string Variable
{
get
{
if (this.Dom.Attributes["Variable"] == null)
return default(string);
return this.Dom.Attributes["Variable"].Value.ToT<string>();
}
set
{
var attr = this.Dom.Attributes.OfType<XmlAttribute>()
.FirstOrDefault(x => x.Name == "Variable");
var oldValue = default(string);
var newValue = value;
if (attr == null)
{
attr = this.Dom.Attributes.Append(this.Dom.OwnerDocument.CreateAttribute("Variable"));
}
else
{
oldValue = this.Dom.Attributes["Variable"].Value.ToT<string>();
} if (value != null)
attr.Value = value.ToString(); if (OnVariable_ProperyChanged != null && oldValue != newValue)
{
OnVariable_ProperyChanged(oldValue, newValue);
}
this.FireAnyProperyChanged("Variable", oldValue, newValue);
}
} public FieldDef CreateFieldDef()
{
return this.Dom.CreateNode<FieldDef>();
} public NodeList<FieldDef> Fields
{
get
{
NodeList<FieldDef> fields = null;
XmlNode fields_node = null; foreach (XmlNode node in this.Dom.ChildNodes)
{
if (node.Name == "Fields")
{
fields_node = node;
fields = new NodeList<FieldDef>(node);
break;
}
} if (fields_node != null)
{
foreach (XmlNode node in fields_node.ChildNodes)
{
fields.AddChild(new FieldDef(node));
}
}
else
{
fields = this.Dom.CreateNode<NodeList<FieldDef>>("Fields"); this.AddChild(fields);
}
return fields;
}
set
{
throw new Exception("cannot set");
}
}
public ClassDef CreateClassDef()
{
return this.Dom.CreateNode<ClassDef>();
} public NodeList<ClassDef> Classes
{
get
{
NodeList<ClassDef> classes = null;
XmlNode classes_node = null; foreach (XmlNode node in this.Dom.ChildNodes)
{
if (node.Name == "Classes")
{
classes_node = node;
classes = new NodeList<ClassDef>(node);
break;
}
} if (classes_node != null)
{
foreach (XmlNode node in classes_node.ChildNodes)
{
classes.AddChild(new ClassDef(node));
}
}
else
{
classes = this.Dom.CreateNode<NodeList<ClassDef>>("Classes"); this.AddChild(classes);
}
return classes;
}
set
{
throw new Exception("cannot set");
}
}
public InitDef CreateInitDef()
{
return this.Dom.CreateNode<InitDef>();
} public InitDef Init
{
get
{
foreach (XmlNode node in this.Dom.ChildNodes)
{
if (node.Name == "InitDef" &&
node.Attributes["variable"] != null &&
node.Attributes["variable"].Value == "Init")
{
return new InitDef(node);
}
}
return null;
}
set
{
if (this.Init != null)
{
this.Init.RemoveSelf();
} var attr = this.Dom.OwnerDocument.CreateAttribute("variable");
attr.Value = "Init";
value.Dom.Attributes.Append(attr); this.Dom.AppendChild(value.Dom);
}
}
public StartStateDef CreateStartStateDef()
{
return this.Dom.CreateNode<StartStateDef>();
} public StartStateDef StartState
{
get
{
foreach (XmlNode node in this.Dom.ChildNodes)
{
if (node.Name == "StartStateDef" &&
node.Attributes["variable"] != null &&
node.Attributes["variable"].Value == "StartState")
{
return new StartStateDef(node);
}
}
return null;
}
set
{
if (this.StartState != null)
{
this.StartState.RemoveSelf();
} var attr = this.Dom.OwnerDocument.CreateAttribute("variable");
attr.Value = "StartState";
value.Dom.Attributes.Append(attr); this.Dom.AppendChild(value.Dom);
}
}
public TerminateStateDef CreateTerminateStateDef()
{
return this.Dom.CreateNode<TerminateStateDef>();
} public TerminateStateDef TerminateState
{
get
{
foreach (XmlNode node in this.Dom.ChildNodes)
{
if (node.Name == "TerminateStateDef" &&
node.Attributes["variable"] != null &&
node.Attributes["variable"].Value == "TerminateState")
{
return new TerminateStateDef(node);
}
}
return null;
}
set
{
if (this.TerminateState != null)
{
this.TerminateState.RemoveSelf();
} var attr = this.Dom.OwnerDocument.CreateAttribute("variable");
attr.Value = "TerminateState";
value.Dom.Attributes.Append(attr); this.Dom.AppendChild(value.Dom);
}
}
public StateDef CreateStateDef()
{
return this.Dom.CreateNode<StateDef>();
} public NodeList<StateDef> States
{
get
{
NodeList<StateDef> states = null;
XmlNode states_node = null; foreach (XmlNode node in this.Dom.ChildNodes)
{
if (node.Name == "States")
{
states_node = node;
states = new NodeList<StateDef>(node);
break;
}
} if (states_node != null)
{
foreach (XmlNode node in states_node.ChildNodes)
{
states.AddChild(new StateDef(node));
}
}
else
{
states = this.Dom.CreateNode<NodeList<StateDef>>("States"); this.AddChild(states);
}
return states;
}
set
{
throw new Exception("cannot set");
}
}
public ParallelDef CreateParallelDef()
{
return this.Dom.CreateNode<ParallelDef>();
} public NodeList<ParallelDef> Parallels
{
get
{
NodeList<ParallelDef> parallels = null;
XmlNode parallels_node = null; foreach (XmlNode node in this.Dom.ChildNodes)
{
if (node.Name == "Parallels")
{
parallels_node = node;
parallels = new NodeList<ParallelDef>(node);
break;
}
} if (parallels_node != null)
{
foreach (XmlNode node in parallels_node.ChildNodes)
{
parallels.AddChild(new ParallelDef(node));
}
}
else
{
parallels = this.Dom.CreateNode<NodeList<ParallelDef>>("Parallels"); this.AddChild(parallels);
}
return parallels;
}
set
{
throw new Exception("cannot set");
}
}
public SubFlowStateDef CreateSubFlowStateDef()
{
return this.Dom.CreateNode<SubFlowStateDef>();
} public NodeList<SubFlowStateDef> SubFlowStates
{
get
{
NodeList<SubFlowStateDef> subFlowStates = null;
XmlNode subFlowStates_node = null; foreach (XmlNode node in this.Dom.ChildNodes)
{
if (node.Name == "SubFlowStates")
{
subFlowStates_node = node;
subFlowStates = new NodeList<SubFlowStateDef>(node);
break;
}
} if (subFlowStates_node != null)
{
foreach (XmlNode node in subFlowStates_node.ChildNodes)
{
subFlowStates.AddChild(new SubFlowStateDef(node));
}
}
else
{
subFlowStates = this.Dom.CreateNode<NodeList<SubFlowStateDef>>("SubFlowStates"); this.AddChild(subFlowStates);
}
return subFlowStates;
}
set
{
throw new Exception("cannot set");
}
}
} public class StartStateDef
: DataNode
{
public StartStateDef
()
: base()
{
} public StartStateDef
(XmlNode dom)
: base(dom)
{
} public StartStateDef
(Document document)
: base(document)
{
} public override string XML_TAG_NAME
{
get
{
return "StartStateDef";
}
set
{
throw new Exception("cannot set");
}
} public event ProperyChanged<string> OnId_ProperyChanged;
public override string Id
{
get
{
if (this.Dom.Attributes["Id"] == null)
return default(string);
return this.Dom.Attributes["Id"].Value.ToT<string>();
}
set
{
var attr = this.Dom.Attributes.OfType<XmlAttribute>()
.FirstOrDefault(x => x.Name == "Id");
var oldValue = default(string);
var newValue = value;
if (attr == null)
{
attr = this.Dom.Attributes.Append(this.Dom.OwnerDocument.CreateAttribute("Id"));
}
else
{
oldValue = this.Dom.Attributes["Id"].Value.ToT<string>();
} if (value != null)
attr.Value = value.ToString(); if (OnId_ProperyChanged != null && oldValue != newValue)
{
OnId_ProperyChanged(oldValue, newValue);
}
this.FireAnyProperyChanged("Id", oldValue, newValue);
}
}
public event ProperyChanged<string> OnName_ProperyChanged;
public string Name
{
get
{
if (this.Dom.Attributes["Name"] == null)
return default(string);
return this.Dom.Attributes["Name"].Value.ToT<string>();
}
set
{
var attr = this.Dom.Attributes.OfType<XmlAttribute>()
.FirstOrDefault(x => x.Name == "Name");
var oldValue = default(string);
var newValue = value;
if (attr == null)
{
attr = this.Dom.Attributes.Append(this.Dom.OwnerDocument.CreateAttribute("Name"));
}
else
{
oldValue = this.Dom.Attributes["Name"].Value.ToT<string>();
} if (value != null)
attr.Value = value.ToString(); if (OnName_ProperyChanged != null && oldValue != newValue)
{
OnName_ProperyChanged(oldValue, newValue);
}
this.FireAnyProperyChanged("Name", oldValue, newValue);
}
} } //此处省略3000行...
}

1.2 数据表及关系设计

1.2.1 数据语法如下:

分享原创可复用且非侵入性代码生成工具(for .net)

1.2.2 生成数据库sql

分享原创可复用且非侵入性代码生成工具(for .net)

1.2.3 生成的sql

 IF OBJECT_ID(N'People',N'U') IS NOT NULL
DROP TABLE [dbo].[People];
CREATE TABLE [dbo].[People](
[Id] int NOT NULL,
[Name] nvarchar(200) ,
[UserId] int ,
[SchoolId] int ,
[Status] int ,
CONSTRAINT [PK_People] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF
, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] GO

1.3 持久化阶段

1.3.1 新建连接串

分享原创可复用且非侵入性代码生成工具(for .net)

分享原创可复用且非侵入性代码生成工具(for .net)

1.3.2 刷新链接,获取数据库所有的表和视图信息

分享原创可复用且非侵入性代码生成工具(for .net)

刷新结果:

分享原创可复用且非侵入性代码生成工具(for .net)

1.3.3 弹出生成操作

分享原创可复用且非侵入性代码生成工具(for .net)

1.3.4 实体层生成

1.3.4.1 生成的EF实体类:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Domain.Entities;
using Domain.AggregateRoot; namespace AAA
{ public class People : Entity, IAggregateRoot
{
public People()
{
}
public People(System.Int32 id)
: base(id)
{
}
/// <summary>
///
/// </summary>
public DateTime? CreateTime
{ get; set; } /// <summary>
///
/// </summary>
public String Name
{ get; set; } /// <summary>
///
/// </summary>
public Int32? SchoolId
{ get; set; } /// <summary>
///
/// </summary>
public Int32? Status
{ get; set; } /// <summary>
///
/// </summary>
public DateTime? UpdateTime
{ get; set; } /// <summary>
///
/// </summary>
public Int32? UserId
{ get; set; } /// <summary>
///
/// </summary>
public virtual User User
{ get; set; } /// <summary>
///
/// </summary>
public virtual School School
{ get; set; } public void AssignFrom(People other)
{
this.CreateTime = other.CreateTime;
this.Name = other.Name;
this.SchoolId = other.SchoolId;
this.Status = other.Status;
this.UpdateTime = other.UpdateTime;
this.UserId = other.UserId;
}
}
}

1.3.4.2 生成的EF映射类:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Domain.Repository; namespace AAA
{ public interface IPeopleRepository : IRepository<People>, IDisposable
{
List<People> GetList(List<Guid> id_list);
}
}

弹出生成Repository操作:

分享原创可复用且非侵入性代码生成工具(for .net)

1.3.4.3 Repository接口代码:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Domain.Repository; namespace AAA
{ public interface IPeopleRepository : IRepository<People>, IDisposable
{
List<People> GetList(List<Guid> id_list);
}
}

1.3.4.4 Specification规约代码:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Domain.Specification; namespace AAA
{ public static class PeopleSpecification
{
public static ISpecification<People> GetList(List<Guid> id_list)
{
return new DirectSpecification<People>(x => id_list.Contains(x.Id));
}
}
}

1.3.4.5 Repository实现代码:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Data;
using Data.Repository; namespace AAA
{ public class PeopleRepository : Repository<People>, IPeopleRepository
{
public PeopleRepository(IQueryableUnitOfWork unitOfWork)
: base(unitOfWork)
{
} public List<People> GetList(List<Guid> id_list)
{
return this.GetAll(PeopleSpecification.GetList(id_list)).ToList();
} public void Dispose()
{
//throw new NotImplementedException();
}
}
}

1.3.5 Service层生成

1.3.5.1 弹出生成WCF操作:
分享原创可复用且非侵入性代码生成工具(for .net)

1.3.5.2 生成DTO代码:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization; namespace AAA
{ [DataContract]
public class PeopleDto
{
/// <summary>
///
/// </summary>
[DataMember]
public DateTime? CreateTime
{ get; set; } /// <summary>
///
/// </summary>
[DataMember]
public Int32 Id
{ get; set; } /// <summary>
///
/// </summary>
[DataMember]
public String Name
{ get; set; } /// <summary>
///
/// </summary>
[DataMember]
public Int32? SchoolId
{ get; set; } /// <summary>
///
/// </summary>
[DataMember]
public Int32? Status
{ get; set; } /// <summary>
///
/// </summary>
[DataMember]
public DateTime? UpdateTime
{ get; set; } /// <summary>
///
/// </summary>
[DataMember]
public Int32? UserId
{ get; set; } }
}

1.3.5.3 生成实体转DTO代码:(建议用automap替代)

  public static PeopleDto ConvertToPeopleDto(People entity)
{
return new PeopleDto{
Id = entity.Id,
Name = entity.Name,
SchoolId = entity.SchoolId,
Status = entity.Status,
UserId = entity.UserId,
};
}

1.3.5.4 生成DTO转实体代码:(建议用automap替代)

  public static People ConvertToPeople(PeopleDto entityDto)
{
return new People(entityDto.Id){
Name = entityDto.Name,
SchoolId = entityDto.SchoolId,
Status = entityDto.Status,
UserId = entityDto.UserId,
};
}

1.3.5.5 生成基本Servie代码:(基础增删改查)

         #region App Service Interface

         ReturnInfoDto AddPeople(PeopleDto peopleDto);

         ReturnInfoDto UpdatePeople(PeopleDto peopleDto);

         ReturnInfoDto<PeopleDto> GetPeople(Guid id);

         ReturnInfoDto<List<PeopleDto>> GetPeopleList(List<Guid> id_list);

         ReturnInfoDto DeletePeople(Guid id);

         ReturnInfoDto DeletePeople(List<Guid> id_list);

         #endregion

         #region App Service Implement

         public ReturnInfoDto AddPeople(PeopleDto peopleDto)
{
var rtnInfo = new ReturnInfoDto();
rtnInfo.Message = string.Empty;
rtnInfo.IsSuccess = false;
try
{
using (var unitOfWork = UnitOfWorkFactory.Create(DbOption.OA))
{
var peopleDB = new PeopleRepository(unitOfWork);
var people = DataConverter.ConvertToPeople(peopleDto);
peopleDB.Add(people);
unitOfWork.Commit();
}
}
catch (Exception ex)
{
rtnInfo.Message = ex.Message;
return rtnInfo;
} rtnInfo.IsSuccess = true;
return rtnInfo;
} public ReturnInfoDto UpdatePeople(PeopleDto peopleDto)
{
var rtnInfo = new ReturnInfoDto();
rtnInfo.Message = string.Empty;
rtnInfo.IsSuccess = false;
try
{
using (var unitOfWork = UnitOfWorkFactory.Create(DbOption.OA))
{
var peopleDB = new PeopleRepository(unitOfWork);
var info = peopleDB.Get(peopleDto.Id);
if (info == null)
{
rtnInfo.Message = "the data is not in system.";
return rtnInfo;
}
var other = DataConverter.ConvertToPeople(peopleDto);
info.AssignFrom(other);
peopleDB.Modify(info);
unitOfWork.Commit();
}
}
catch (Exception ex)
{
rtnInfo.Message = ex.Message;
return rtnInfo;
} rtnInfo.IsSuccess = true;
return rtnInfo;
} public ReturnInfoDto<PeopleDto> GetPeople(Guid id)
{
var rtnInfo = new ReturnInfoDto<PeopleDto>();
rtnInfo.Message = string.Empty;
rtnInfo.IsSuccess = false;
try
{
using (var unitOfWork = UnitOfWorkFactory.Create(DbOption.OA))
{
var peopleDB = new PeopleRepository(unitOfWork);
var people = peopleDB.Get(id);
if(people != null)
{
rtnInfo.Data = DataConverter.ConvertToPeopleDto(people);
}
}
}
catch (Exception ex)
{
rtnInfo.Message = ex.Message;
return rtnInfo;
} rtnInfo.IsSuccess = true;
return rtnInfo;
} public ReturnInfoDto<List<PeopleDto>> GetPeopleList(List<Guid> id_list)
{
var rtnInfo = new ReturnInfoDto<List<PeopleDto>>();
rtnInfo.Message = string.Empty;
rtnInfo.IsSuccess = false;
rtnInfo.Data = new List<PeopleDto>();
try
{
using (var unitOfWork = UnitOfWorkFactory.Create(DbOption.OA))
{
var peopleDB = new PeopleRepository(unitOfWork);
var list = peopleDB.GetList(id_list);
if(list != null && list.Count > )
{
list.ForEach( x => rtnInfo.Data.Add(DataConverter.ConvertToPeopleDto(x)));
}
}
}
catch (Exception ex)
{
rtnInfo.Message = ex.Message;
return rtnInfo;
} rtnInfo.IsSuccess = true;
return rtnInfo;
} public ReturnInfoDto DeletePeople(Guid id)
{
var rtnInfo = new ReturnInfoDto();
rtnInfo.Message = string.Empty;
rtnInfo.IsSuccess = false;
try
{
using (var unitOfWork = UnitOfWorkFactory.Create(DbOption.OA))
{
var peopleDB = new PeopleRepository(unitOfWork);
var people = peopleDB.Get(id);
if(people == null )
{
rtnInfo.Message = "the data is not in system.";
return rtnInfo;
}
//people.Available = false;
//peopleDB.Modify(people);
peopleDB.Remove(people);
unitOfWork.Commit();
}
}
catch (Exception ex)
{
rtnInfo.Message = ex.Message;
return rtnInfo;
} rtnInfo.IsSuccess = true;
return rtnInfo;
} public ReturnInfoDto DeletePeople(List<Guid> id_list)
{
var rtnInfo = new ReturnInfoDto();
rtnInfo.Message = string.Empty;
rtnInfo.IsSuccess = false;
try
{
using (var unitOfWork = UnitOfWorkFactory.Create(DbOption.OA))
{
var peopleDB = new PeopleRepository(unitOfWork);
var people_list = peopleDB.GetList(id_list);
foreach (var people in people_list)
{
//people.Available = false;
//peopleDB.Modify(people);
peopleDB.Remove(people);
}
unitOfWork.Commit();
}
}
catch (Exception ex)
{
rtnInfo.Message = ex.Message;
return rtnInfo;
} rtnInfo.IsSuccess = true;
return rtnInfo;
} #endregion #region Distribute Service Interface [OperationContract]
[WithoutAuthorization]
[FaultContractAttribute(typeof(UnAuthorization))]
ReturnInfoDto AddPeople(PeopleDto peopleDto); [OperationContract]
[WithoutAuthorization]
[FaultContractAttribute(typeof(UnAuthorization))]
ReturnInfoDto UpdatePeople(PeopleDto peopleDto); [OperationContract]
[WithoutAuthorization]
[FaultContractAttribute(typeof(UnAuthorization))]
ReturnInfoDto<PeopleDto> GetPeople(Guid id); [OperationContract]
[WithoutAuthorization]
[FaultContractAttribute(typeof(UnAuthorization))]
ReturnInfoDto<List<PeopleDto>> GetPeopleList(List<Guid> id_list); [OperationContract]
[WithoutAuthorization]
[FaultContractAttribute(typeof(UnAuthorization))]
ReturnInfoDto DeletePeople(Guid id); [OperationContract]
[WithoutAuthorization]
[FaultContractAttribute(typeof(UnAuthorization))]
ReturnInfoDto DeletePeopleList(List<Guid> id_list); #endregion #region Distribute Service Implement public ReturnInfoDto AddPeople(PeopleDto peopleDto)
{
return _appService.AddPeople(peopleDto);
} public ReturnInfoDto UpdatePeople(PeopleDto peopleDto)
{
return _appService.UpdatePeople(peopleDto);
} public ReturnInfoDto<PeopleDto> GetPeople(Guid id)
{
return _appService.GetPeople( id );
} public ReturnInfoDto<List<PeopleDto>> GetPeopleList(List<Guid> id_list)
{
return _appService.GetPeopleList( id_list );
} public ReturnInfoDto DeletePeople(Guid id)
{
return _appService.DeletePeople( id );
} public ReturnInfoDto DeletePeopleList(List<Guid> id_list)
{
return _appService.DeletePeople( id_list );
} #endregion #region Service Layer public ReturnInfo AddPeople(PeopleInfo peopleInfo)
{
var result = new ReturnInfo(); try
{
var dto = DataConverter.ConvertToPeopleDto(peopleInfo);
var rslt = serviceClient.Invoke<ReturnInfoDto>(x => x.AddPeople(dto));
result.IsSuccess = rslt.IsSuccess;
result.Message = rslt.Message; }
catch (Exception e)
{
LogHelper.Error(e);
result.IsSuccess = false;
result.Message = "call service error";
} return result;
} public ReturnInfo UpdatePeople(PeopleInfo peopleInfo)
{
var result = new ReturnInfo(); try
{
var dto = DataConverter.ConvertToPeopleDto(peopleInfo);
var rslt = serviceClient.Invoke<ReturnInfoDto>(x => x.UpdatePeople(dto));
result.IsSuccess = rslt.IsSuccess;
result.Message = rslt.Message; }
catch (Exception e)
{
LogHelper.Error(e);
result.IsSuccess = false;
result.Message = "call service error";
} return result;
} public ReturnInfo<PeopleInfo> GetPeople(Guid id)
{
var result = new ReturnInfo<PeopleInfo>(); try
{
var rslt = serviceClient.Invoke<ReturnInfoDto<PeopleDto>>(x => x.GetPeople(id));
result.Data = DataConverter.ConvertToPeopleInfo(rslt.Data);
result.IsSuccess = rslt.IsSuccess;
result.Message = rslt.Message; }
catch (Exception e)
{
LogHelper.Error(e);
result.IsSuccess = false;
result.Message = "call service error";
} return result;
} public ReturnInfo<List<PeopleInfo>> GetPeopleList(List<Guid> id_list)
{
var result = new ReturnInfo<List<PeopleInfo>>();
result.Data = new List<PeopleInfo>(); try
{
var rslt = serviceClient.Invoke<ReturnInfoDto<List<PeopleDto>>>(x => x.GetPeopleList(id_list));
result.IsSuccess = rslt.IsSuccess;
result.Message = rslt.Message;
if (rslt.IsSuccess )
{
if (rslt.Data != null && rslt.Data.Count > )
{
rslt.Data.ForEach(x => result.Data.Add(DataConverter.ConvertToPeopleInfo(x)));
}
}
}
catch (Exception e)
{
LogHelper.Error(e);
result.IsSuccess = false;
result.Message = "call service error";
} return result;
} public ReturnInfo DeletePeople(Guid id)
{
var result = new ReturnInfo(); try
{
var rslt = serviceClient.Invoke<ReturnInfoDto>(x => x.DeletePeople(id));
result.IsSuccess = rslt.IsSuccess;
result.Message = rslt.Message; }
catch (Exception e)
{
LogHelper.Error(e);
result.IsSuccess = false;
result.Message = "call service error";
} return result;
} public ReturnInfo DeletePeople(List<Guid> id_list)
{
var result = new ReturnInfo(); try
{
var rslt = serviceClient.Invoke<ReturnInfoDto>(x => x.DeletePeopleList(id_list));
result.IsSuccess = rslt.IsSuccess;
result.Message = rslt.Message; }
catch (Exception e)
{
LogHelper.Error(e);
result.IsSuccess = false;
result.Message = "call service error";
} return result;
} #endregion

1.3.5.6 生成CCFlowService:此处省略(比较私有)

1.3.6 Web层生成

1.3.6.1 弹出ViewMode生成操作:

分享原创可复用且非侵入性代码生成工具(for .net)

1.3.6.2 生成ViewModel代码:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization; namespace AAA
{ public class PeopleInfo
{
/// <summary>
///
/// </summary>
public DateTime? CreateTime
{ get; set; } /// <summary>
///
/// </summary>
public Int32 Id
{ get; set; } /// <summary>
///
/// </summary>
public String Name
{ get; set; } /// <summary>
///
/// </summary>
public Int32? SchoolId
{ get; set; } /// <summary>
///
/// </summary>
public Int32? Status
{ get; set; } /// <summary>
///
/// </summary>
public DateTime? UpdateTime
{ get; set; } /// <summary>
///
/// </summary>
public Int32? UserId
{ get; set; } }
}

1.3.6.3 生成ViewModel转WCF DTO代码:(建议用automapper替代)

  public static PeopleDto ConvertToPeopleDto(PeopleInfo info)
{
return new PeopleDto{
Id = info.Id,
Name = info.Name,
SchoolId = info.SchoolId,
Status = info.Status,
UserId = info.UserId,
};
}

1.3.6.4 生成WCF DTO转ViewModel代码:(建议用automapper替代)

  public static PeopleInfo ConvertToPeopleInfo(PeopleDto dto )
{
return new PeopleInfo(){
Id = dto.Id,
Name = dto.Name,
SchoolId = dto.SchoolId,
Status = dto.Status,
UserId = dto.UserId,
};
}

1.3.6.5 弹出生成View操作:
分享原创可复用且非侵入性代码生成工具(for .net)

1.3.6.6 生成编辑页面Model代码:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
namespace AAA
{ public class PeopleInfo
{
/// <summary>
///
/// </summary>
public DateTime? CreateTime
{ get; set; } /// <summary>
///
/// </summary>
public Int32 Id
{ get; set; } /// <summary>
///
/// </summary>
public String Name
{ get; set; } /// <summary>
///
/// </summary>
public Int32? SchoolId
{ get; set; } /// <summary>
///
/// </summary>
public Int32? Status
{ get; set; } /// <summary>
///
/// </summary>
public DateTime? UpdateTime
{ get; set; } /// <summary>
///
/// </summary>
public Int32? UserId
{ get; set; } }
}

1.3.6.7 生成编辑页面代码:

 @model EditPeopleModel
@{
Layout = "~/Views/Shared/_SimpleLayout.cshtml"; if(this.Model.Id.HasValue){
ViewBag.Title = "Edit Item";
}
else{
ViewBag.Title = "Add Item";
}
} @section js{
<script src="../../Scripts/jquery.validate.js" type="text/javascript"></script>
<script language = "javascript" type="text/javascript">
function OnClose(refresh) {
if (parent.MsgBox != undefined) { if (refresh) {
if (parent.MsgBox.Callback != null) {
parent.MsgBox.Callback();
parent.MsgBox.Callback = null;
}
}
parent.MsgBox.Callback = null; parent.MsgBox.Close(); }
else {
window.close();
}
} $(function () { if (parent.MsgBox != undefined) {
parent.MsgBox.CancelCallback = true;
} $('#btnSaveAndClose').click(function () { $('#IsSave').val(true); $('#editForm').submit(); }); $('#btnCancel').click(function () { OnClose(); }); if ($('#IsSave').val() == 'True') {
var msg = $('#ErrorMsg').val();
if (msg == '') {
jAlert('Save Success','Tip',function(){
OnClose(true);
});
}
else {
jAlert(msg);
}
} $('#somecontrolId').attr('readonly','true').addClass('readonly'); $('select').each(function(){
$(this).val($(this).attr('_value'));
}); var validator = $('#editForm').validate({
debug: true, //调试模式取消submit的默认提交功能
errorClass: 'error', //默认为错误的样式类为:error
focusInvalid: false,
onkeyup: false,
submitHandler: function (form) { //表单提交句柄,为一回调函数,带一个参数:form
//alert('提交表单');
form.submit(); //提交表单
},
rules: { //定义验证规则,其中属性名为表单的name属性
Name:{
},
SchoolId:{
},
Status:{
},
UserId:{
} }, messages: { //自定义验证消息
PurchasePlan: {
//required: 'required !',
//minlength: $.format('用户名至少要{0}个字符!'),
//remote: $.format('{0}已经被占用')
},
},
errorPlacement: function (error, element) {
var noHtml = '<div class="notification error" for="' + error.attr('for') + '">' +
"<a class=\"close\" ><img alt=\"close\" title=\"Close this notification\" src=\"/Content/images/cross_grey_small.png\"></a>" +
'<div>' + error.html() + '</div>' + '</div>';
var notification = element.parent().find('div');
if (notification.length > 0) {
notification.remove();
}
element.parent().find('span').hide();
$(noHtml).appendTo(element.parent());
error.html('');
error.appendTo(element.parent());
},
highlight: function (element, errorClass) { //针对验证的表单设置高亮
//$(element).addClass(errorClass);
},
success: function (element) {
element.parent().find('span').show();
element.parent().find('div.error,label.validateError').remove();
}});
});
</script> } @section css{ <style type="text/css">
body
{
background: none;
}
.field
{
vertical-align: middle;
clear: both;
padding-left: 5px;
padding-top: 5px;
padding-bottom: 5px;
}
.field_name
{
width: 160px;
float: left;
padding-right: 10px;
padding-top: 10px;
margin: 0 auto;
}
.field_value
{
width: 260px;
float: left;
}
custom-combobox input
{
width: 120px;
}
.operation
{
margin-top: 20px;
padding-top: 20px;
clear: both;
}
input
{
width: 206px;
}
select
{
width: 220px;
}
.readonly
{
background-color: #e6e6e6;
}
</style> } <div class="tabmini-content">
<form method="post" id="editForm" class="form" action="/xxx/EditPeopleItem"> <input type='hidden' id='Id' name='Id' value='@Model.Id' />
<input type='hidden' id='IsPostBack' name='IsPostBack' value='true' />
<input type='hidden' id='IsSave' name='IsSave' value='@Model.IsSave' />
<input type='hidden' id='ErrorMsg' name='ErrorMsg' value='@Model.ErrorMsg' /> <fieldset class="ConfigArea">
<div class="field">
<div class="field_name">
<label>Name:</label>
</div>
<div class="field_value">
<input type="text" name="Name" id="Name" value="@Model.Name"/>
</div>
</div>
<div class="field">
<div class="field_name">
<label>SchoolId:</label>
</div>
<div class="field_value">
<input type="text" name="SchoolId" id="SchoolId" value="@Model.SchoolId"/>
</div>
</div>
<div class="field">
<div class="field_name">
<label>Status:</label>
</div>
<div class="field_value">
<input type="text" name="Status" id="Status" value="@Model.Status"/>
</div>
</div>
<div class="field">
<div class="field_name">
<label>UserId:</label>
</div>
<div class="field_value">
<input type="text" name="UserId" id="UserId" value="@Model.UserId"/>
</div>
</div>
<div class='operation'>
<a class='button blue' id='btnSaveAndClose'>Save&Close</a> <a class='button blue'
id='btnCancel'>Cancel</a>
</div>
</fieldset>
</form>
</div>

1.3.6.8 弹出生成MVC代码操作:
分享原创可复用且非侵入性代码生成工具(for .net)

1.3.6.9 生成Action代码:

     public ActionResult EditPeople(EditPeopleModel model)
{ //model.UserId = Motorola.ZCH49.OaSystem.WebSite.Models.User.GetCurrentUser(this).Id;
model.Action();
return View(model); } [HttpPost]
public ActionResult DeletePeople(Guid id)
{
var model = new ReturnInfo(); if (id == default(Guid))
{
model.Message = "no id";
}
else
{
model = EditPeopleModel.DeletePeople(id);
}
return Json(model, JsonRequestBehavior.AllowGet); } [HttpPost]
public ActionResult DeletePeople(List<Guid> idList)
{
var model = new ReturnInfo(); if (idList == null || idList.Count == )
{
model.Message = "no id";
}
else
{
model = EditPeopleModel.DeletePeople(idList);
}
return Json(model, JsonRequestBehavior.AllowGet); }

1.3.7 视图的相关操作和表操作一样
分享原创可复用且非侵入性代码生成工具(for .net)

1.4 自定义查询(解决常见查询动态参数化问题)

1.4.1 创建查询集(类似文件夹/目录概念,对查询进行管理)

分享原创可复用且非侵入性代码生成工具(for .net)

1.4.2 创建查询

分享原创可复用且非侵入性代码生成工具(for .net)

1.4.3 编辑查询

语法和语义同标准sql,主要用于动态的参数化查询,一下为一个常用查询的参数化(分页,各字段的排序,参数提取)

分享原创可复用且非侵入性代码生成工具(for .net)

实例代码主要是EF查相关,其他的代码生成省略。

1.4.3.1 生成的查询条件类:

 using System;
using System.Collections.Generic; namespace xxx
{
public class People_Query_Condition
{
public enum OrderByType
{
CreateTime_Asc,
CreateTime_Desc,
Id_Asc,
Id_Desc,
Name_Asc,
Name_Desc,
SchoolId_Asc,
SchoolId_Desc,
Status_Asc,
Status_Desc,
UpdateTime_Asc,
UpdateTime_Desc,
UserId_Asc,
UserId_Desc, } public OrderByType? OrderBy { get; set; } public DateTime? CreateTime_Begin
{ get; set; } public DateTime? CreateTime_End
{ get; set; } public int? Id
{ get; set; } public List<int> Ids
{ get; set; } public string Name
{ get; set; } public int? SchoolId
{ get; set; } public int? Status
{ get; set; } public int? UserId
{ get; set; } public int PageIndex { get; set; }
public int PageSize { get; set; }
public int RecordCount { get; set; }
public People_Query_Condition()
{
this.Ids = new List<int>();
}
}
}

1.4.3.2 生成的查询DTO类:

 using System;
using System.Collections.Generic;
using System.Runtime.Serialization; namespace xxx
{
[DataContract]
public class People_Query_ConditionDto
{
[DataContract]
public enum OrderByType
{
[EnumMember]
CreateTime_Asc,
[EnumMember]
CreateTime_Desc,
[EnumMember]
Id_Asc,
[EnumMember]
Id_Desc,
[EnumMember]
Name_Asc,
[EnumMember]
Name_Desc,
[EnumMember]
SchoolId_Asc,
[EnumMember]
SchoolId_Desc,
[EnumMember]
Status_Asc,
[EnumMember]
Status_Desc,
[EnumMember]
UpdateTime_Asc,
[EnumMember]
UpdateTime_Desc,
[EnumMember]
UserId_Asc,
[EnumMember]
UserId_Desc, } [DataMember]
public OrderByType? OrderBy { get; set; } [DataMember]
public DateTime? CreateTime_Begin
{ get; set; } [DataMember]
public DateTime? CreateTime_End
{ get; set; } [DataMember]
public int? Id
{ get; set; } [DataMember]
public List<int> Ids
{ get; set; } [DataMember]
public string Name
{ get; set; } [DataMember]
public int? SchoolId
{ get; set; } [DataMember]
public int? Status
{ get; set; } [DataMember]
public int? UserId
{ get; set; } [DataMember]
public int PageIndex { get; set; }
[DataMember]
public int PageSize { get; set; }
[DataMember]
public int RecordCount { get; set; }
public People_Query_ConditionDto()
{
this.Ids = new List<int>();
}
}
}

1.4.3.3 生成的EF规约代码:

 public static ISpecification<People> People_Query(People_Query_Condition condition)
{
ISpecification<People> id_spec = null;
if (!condition.Id.HasValue)
{
id_spec = new DirectSpecification<People>(x=> true);
}
else{
id_spec = new DirectSpecification<People>(x=>
x.Id == condition.Id
);
} ISpecification<People> ids_spec = null;
if (condition.Ids == null || condition.Ids.Count == )
{
ids_spec = new DirectSpecification<People>(x=> true);
}
else{
} ISpecification<People> name_spec = null;
if (string.IsNullOrWhiteSpace(condition.Name))
{
name_spec = new DirectSpecification<People>(x=> true);
}
else{
name_spec = new DirectSpecification<People>(x=>
x.Name.Contains(condition.Name)
);
} ISpecification<People> schoolId_spec = null;
if (!condition.SchoolId.HasValue)
{
schoolId_spec = new DirectSpecification<People>(x=> true);
}
else{
schoolId_spec = new DirectSpecification<People>(x=>
x.SchoolId == condition.SchoolId
);
} ISpecification<People> status_spec = null;
if (!condition.Status.HasValue)
{
status_spec = new DirectSpecification<People>(x=> true);
}
else{
status_spec = new DirectSpecification<People>(x=>
x.Status == condition.Status
);
} ISpecification<People> userId_spec = null;
if (!condition.UserId.HasValue)
{
userId_spec = new DirectSpecification<People>(x=> true);
}
else{
userId_spec = new DirectSpecification<People>(x=>
x.UserId == condition.UserId
);
} ISpecification<People> createTime_Begin_spec = null;
if (!condition.CreateTime_Begin.HasValue)
{
createTime_Begin_spec = new DirectSpecification<People>(x=> true);
}
else{
createTime_Begin_spec = new DirectSpecification<People>(x=>
x.CreateTime >= condition.CreateTime_Begin
);
} ISpecification<People> createTime_End_spec = null;
if (!condition.CreateTime_End.HasValue)
{
createTime_End_spec = new DirectSpecification<People>(x=> true);
}
else{
createTime_End_spec = new DirectSpecification<People>(x=>
x.CreateTime <= condition.CreateTime_End
);
} var name_spec = new DirectSpecification<People>(x=>
(x.Name??"") != ""
); ISpecification<People> id_ids = new AndSpecification<People>(id_spec,ids_spec);
ISpecification<People> id_ids_name = new AndSpecification<People>(id_ids,name_spec);
ISpecification<People> id_ids_name_schoolId = new AndSpecification<People>(id_ids_name,schoolId_spec);
ISpecification<People> id_ids_name_schoolId_status = new AndSpecification<People>(id_ids_name_schoolId,status_spec);
ISpecification<People> id_ids_name_schoolId_status_userId = new AndSpecification<People>(id_ids_name_schoolId_status,userId_spec);
ISpecification<People> id_ids_name_schoolId_status_userId_createTime_Begin = new AndSpecification<People>(id_ids_name_schoolId_status_userId,createTime_Begin_spec);
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);
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);
return id_ids_name_schoolId_status_userId_createTime_Begin_createTime_End_name;
}

1.4.3.4 生成的EF存取代码:

 public PageOfReturn<People> People_Query( People_Query_Condition condition )
{
var data = this.GetAll( PeopleSpecification.People_Query(condition ));
if( condition.OrderBy.HasValue )
{
switch(condition.OrderBy)
{
case People_Query_Condition.OrderByType.CreateTime_Asc:
data = data.OrderBy(x=>x.CreateTime);
break;
case People_Query_Condition.OrderByType.CreateTime_Desc:
data = data.OrderByDescending(x=>x.CreateTime);
break;
case People_Query_Condition.OrderByType.Id_Asc:
data = data.OrderBy(x=>x.Id);
break;
case People_Query_Condition.OrderByType.Id_Desc:
data = data.OrderByDescending(x=>x.Id);
break;
case People_Query_Condition.OrderByType.Name_Asc:
data = data.OrderBy(x=>x.Name);
break;
case People_Query_Condition.OrderByType.Name_Desc:
data = data.OrderByDescending(x=>x.Name);
break;
case People_Query_Condition.OrderByType.SchoolId_Asc:
data = data.OrderBy(x=>x.SchoolId);
break;
case People_Query_Condition.OrderByType.SchoolId_Desc:
data = data.OrderByDescending(x=>x.SchoolId);
break;
case People_Query_Condition.OrderByType.Status_Asc:
data = data.OrderBy(x=>x.Status);
break;
case People_Query_Condition.OrderByType.Status_Desc:
data = data.OrderByDescending(x=>x.Status);
break;
case People_Query_Condition.OrderByType.UpdateTime_Asc:
data = data.OrderBy(x=>x.UpdateTime);
break;
case People_Query_Condition.OrderByType.UpdateTime_Desc:
data = data.OrderByDescending(x=>x.UpdateTime);
break;
case People_Query_Condition.OrderByType.UserId_Asc:
data = data.OrderBy(x=>x.UserId);
break;
case People_Query_Condition.OrderByType.UserId_Desc:
data = data.OrderByDescending(x=>x.UserId);
break;
default:
break;
}
}
var result = new PageOfReturn<People>();
result.RecordCount = data.Count();
result.PageIndex = condition.PageIndex;
result.PageSize = condition.PageSize;
result.PageRecords = data.Skip(condition.PageSize * (condition.PageIndex - )).Take(condition.PageSize).ToList();
return result;
}

1.4.3.5 其他层如Service,Web层。基本上代码少量改动一下就可以实现一个列表页面。实例代码省略

1.4.4 多表查询

分享原创可复用且非侵入性代码生成工具(for .net)

1.4.4.1 生成的查询条件类:

 using System;
using System.Collections.Generic; namespace xxx
{
public class GetPeopleInfo_Condition
{
public string SchoolName
{ get; set; } public int? Status
{ get; set; } public GetPeopleInfo_Condition()
{
}
}
}

1.4.4.2 生成的查询条件DTO类:

 using System;
using System.Collections.Generic;
using System.Runtime.Serialization; namespace xxx
{
[DataContract]
public class GetPeopleInfo_ConditionDto
{
[DataMember]
public string SchoolName
{ get; set; } [DataMember]
public int? Status
{ get; set; } public GetPeopleInfo_ConditionDto()
{
}
}
}

1.4.4.3 生成的结果类:

 using System;
using System.Linq;
using System.Data;
using System.Collections.Generic; namespace xxx
{
public class PeopleInfo
{
public DateTime? CreateTime
{ get; set; } public int Id
{ get; set; } public string Name
{ get; set; } public int? SchoolId
{ get; set; } public int? Status
{ get; set; } public DateTime? UpdateTime
{ get; set; } public int? UserId
{ get; set; } public string SchoolName//来自表 School
{ get; set; } public string UserEmail //来自表 C_Users
{ get; set; } }
}

1.4.4.4 生成的EF代码(多表关联不再需要规约):

 public List<PeopleInfo> GetPeopleInfo( GetPeopleInfo_Condition condition )
{
using (var unitOfWork = UnitOfWorkFactory.Create(DbOption.OA))
{
var p_q = ctx.Set<People>().AsQueryable();
if(condition.Status != null )
{
p_q = p_q.Where(x=>x.Status == condition.Status);
} var s_q = ctx.Set<School>().AsQueryable();
if(condition.SchoolName != null )
{
s_q = s_q.Where(x=>x.Name == condition.SchoolName);
} var u_q = ctx.Set<User>().AsQueryable();
var q = p_q; var q_1 = q.GroupJoin(s_q,p=>p.SchoolId,s=>s.Id,
(p,s)=>new { p,s = s.DefaultIfEmpty() })
.SelectMany(item=>item.s.Select(s=> new {item.p,s})); var q_2 = q_1.GroupJoin(u_q,p=>p.p.UserId,u=>u.UserId,
(p,u)=>new { p,u = u.DefaultIfEmpty() })
.SelectMany(item=>item.u.Select(u=> new {item.p.p,item.p.s,u})); var q_final = q_2.Where(x=>
true); var list = q_final.Select(x=>new PeopleInfo(){
SchoolId = x.p.SchoolId,
Name = x.p.Name,
CreateTime = x.p.CreateTime,
UpdateTime = x.p.UpdateTime,
Id = x.p.Id,
Status = x.p.Status,
UserId = x.p.UserId,
SchoolName = x.SchoolName,
UserEmail = x.UserEmail,
});
return list.ToList();
}
}

1.4.5 高级查询

1.4.5.1 分组查询

分享原创可复用且非侵入性代码生成工具(for .net)

1.4.5.2 选项查询

1.4.5.2.1 {'op','all'} 一个字段产生多个查询条件

分享原创可复用且非侵入性代码生成工具(for .net)

1.4.5.2.2 对条件查询进行条件:在某些参数非空下区域内参数才有效

分享原创可复用且非侵入性代码生成工具(for .net)

写这么多,感觉需要控制篇幅,查询告一段落~

1.5 反向工程(持久阶段元数据更新设计阶段元数据)

使设计永不过期

分享原创可复用且非侵入性代码生成工具(for .net) -----------> 分享原创可复用且非侵入性代码生成工具(for .net)

1.6 生成数据词典

分享原创可复用且非侵入性代码生成工具(for .net)  ----------->

分享原创可复用且非侵入性代码生成工具(for .net)

终于码完了。

2. 总结:

  生成器基本上涉及了数据系统资源管理的方方面面(数据操作,应用层,服务层,展现层),能节约大量的开发时间。使工程师更注重业务知识,

举例来说,用来这套开发工具后,我们团队加班变得非常少,项目进度和预期的基本吻合。拙笔仓促,如有笔误和不妥请谅解,希望听到大家的意见和建议,thanks。