winform+wcf搭建商户管理系统(1)-wcf服务的搭建
1.业务分析和数据库的搭建
对业务进行整体的需求分析,然后建立相应的业务逻辑关系以及表结构。
2.通过DDD代码生成工具构建基础WCF服务模型
这个领域驱动模型服务的生成工具(VS插件工具)是前些时,花一些时间完成的,主要包括有数据库优先和代码优先两种代码生成模式,业务层自动加入了增、删、改查的基本功能。
具体的各层如下图
1.基础结构层主要封装EF底层方法,处理映射关系等
Map
using iTelluro.Explorer.YatMing.Domain.Entities; using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Linq.Expressions; using System.ComponentModel.DataAnnotations.Schema; using System.Data.Entity; using System.Data; using System.Data.SqlClient; using System.Data.Entity.ModelConfiguration; namespace iTelluro.Explorer.YatMing.Infrastructure.Context.Map { internal class TBaseInfoMap : EntityTypeConfiguration<T_BaseInfo> { public TBaseInfoMap(string schema = "dbo") { ToTable("T_BaseInfo", schema); HasKey(x => x.BaseInfoId); Property(x => x.BaseInfoId).HasColumnName("BaseInfoId").IsRequired().IsFixedLength().IsUnicode(false).HasMaxLength(36).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); Property(x => x.MerchantName).HasColumnName("MerchantName").IsRequired().IsUnicode(false).HasMaxLength(50); Property(x => x.MerchantBoss).HasColumnName("MerchantBoss").IsOptional().IsUnicode(false).HasMaxLength(10); Property(x => x.MerchantSex).HasColumnName("MerchantSex").IsOptional().IsFixedLength().IsUnicode(false).HasMaxLength(2); Property(x => x.MerchantTel).HasColumnName("MerchantTel").IsOptional().IsUnicode(false).HasMaxLength(13); Property(x => x.MerchantAdd).HasColumnName("MerchantAdd").IsOptional().IsUnicode(false).HasMaxLength(100); Property(x => x.MerchantId).HasColumnName("MerchantId").IsOptional().IsFixedLength().IsUnicode(false).HasMaxLength(36); Property(x => x.Feedback).HasColumnName("Feedback").IsOptional().IsUnicode(false).HasMaxLength(500); Property(x => x.Lon).HasColumnName("Lon").IsOptional(); Property(x => x.Lat).HasColumnName("Lat").IsOptional(); Property(x => x.Logo).HasColumnName("Logo").IsOptional().HasMaxLength(2147483647); HasOptional(a => a.TMerchantType).WithMany(b => b.TBaseInfoes).HasForeignKey(c => c.MerchantId).WillCascadeOnDelete(true); // FK_T_BaseInfo_T_MerchantType } } }
封装EF基础方法(包括实体的增删改查、以及SQL语句的执行)
using iTelluro.Explorer.Domain.CodeFirst.Seedwork; using System; using System.Collections.Generic; using System.Data; using System.Data.Entity; using System.Linq; using System.Text; using iTelluro.Explorer.YatMing.Infrastructure.Context.Extention; using System.Data.Entity.Infrastructure; using iTelluro.Explorer.Infrastruct.CodeFirst.Seedwork; using System.Data.SqlClient; namespace iTelluro.Explorer.YatMing.Infrastructure.Context { public partial class YatMingContext : IQueryableUnitOfWork { /// <summary> /// 获取 当前单元操作是否已被提交 /// </summary> public bool IsCommitted { get; private set; } #region IQueryableUnitOfWork 成员 以前 public DbSet<TEntity> CreateSet<TEntity>() where TEntity : class { return base.Set<TEntity>(); } public void Attach<TEntity>(TEntity item) where TEntity : class { //attach and set as unchanged base.Entry<TEntity>(item).State = System.Data.EntityState.Unchanged; } public void SetModified<TEntity>(TEntity item) where TEntity : class { //this operation also attach item in object state manager base.Entry<TEntity>(item).State = System.Data.EntityState.Modified; } public void ApplyCurrentValues<TEntity>(TEntity original, TEntity current) where TEntity : class { //if it is not attached, attach original and set current values base.Entry<TEntity>(original).CurrentValues.SetValues(current); } #endregion #region IQueryableUnitOfWork 成员 /// <summary> /// 提交当前操作的结果 /// </summary> /// <param name="validateOnSaveEnabled">保存时是否自动验证跟踪实体</param> /// <returns></returns> public int Commit(bool validateOnSaveEnabled = true) { if (IsCommitted) { return 0; } try { int result = this.SaveChanges(validateOnSaveEnabled); IsCommitted = true; return result; } catch (DbUpdateException e) { if (e.InnerException != null && e.InnerException.InnerException is SqlException) { SqlException sqlEx = e.InnerException.InnerException as SqlException; throw new Exception("提交数据更新时发生异常:", sqlEx); } throw; } } /// <summary> /// 把当前操作回滚成未提交状态 /// </summary> public void Rollback() { IsCommitted = false; } /// <summary> /// 释放资源 /// </summary> public void Dispose() { if (!IsCommitted) { Commit(); } this.Dispose(); } /// <summary> /// 执行Sql语句(查询) /// </summary> /// <typeparam name="T"></typeparam> /// <param name="sqlQuery">Sql语句</param> /// <param name="parameters">参数</param> /// <returns>返回查询的结果</returns> public IQueryable<T> ExecuteQuery<T>(string sqlQuery, params object[] parameters) { return base.Database.SqlQuery<T>(sqlQuery, parameters).AsQueryable(); } /// <summary> /// 执行Sql语句(查,删,改) /// </summary> /// <param name="sqlCommand">Sql语句</param> /// <param name="parameters">参数</param> /// <returns>影响的行数</returns> public int ExecuteCommand(string sqlCommand, params object[] parameters) { return base.Database.ExecuteSqlCommand(sqlCommand, parameters); } /// <summary> /// 添加实体 /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="entity"></param> public void AddEntity<TEntity>(TEntity entity) where TEntity : Entity { EntityState state = this.Entry(entity).State; if (state == EntityState.Detached) { this.Entry(entity).State = EntityState.Added; } IsCommitted = false; } /// <summary> /// 批量添加实体 /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="entities"></param> public void AddEntities<TEntity>(IEnumerable<TEntity> entities) where TEntity : Entity { try { this.Configuration.AutoDetectChangesEnabled = false; foreach (TEntity entity in entities) { AddEntity(entity); } } finally { this.Configuration.AutoDetectChangesEnabled = true; } } /// <summary> /// 删除实体 /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="entity"></param> public void DeleteEntity<TEntity>(TEntity entity) where TEntity : Entity { this.Entry(entity).State = EntityState.Deleted; } /// <summary> /// 批量删除实体 /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="entities"></param> public void DeleteEntities<TEntity>(IEnumerable<TEntity> entities) where TEntity : Entity { try { this.Configuration.AutoDetectChangesEnabled = false; foreach (TEntity entity in entities) { DeleteEntity(entity); } } finally { this.Configuration.AutoDetectChangesEnabled = true; } } /// <summary> /// 更新实体 /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="entity"></param> public void UpdateEntity<TEntity>(TEntity entity) where TEntity : Entity { this.Update<TEntity>(entity); IsCommitted = false; } /// <summary> /// 批量更新实体 /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="entities"></param> public void UpdateEntities<TEntity>(IEnumerable<TEntity> entities) where TEntity : Entity { this.Update<TEntity>(entities.ToArray()); IsCommitted = false; } #endregion } }
2.实体层主要给服务提供实体容器以及描述实体所对应的关系
using System; using System.Collections.Generic; using iTelluro.Explorer.Domain.CodeFirst.Seedwork; namespace iTelluro.Explorer.YatMing.Domain.Entities { public class T_BaseInfo : Entity { private string _baseinfoid; public string BaseInfoId { get { return _baseinfoid; } set { this.Id = value; this._baseinfoid = value; } } // BaseInfoId (Primary key) public string MerchantName { get; set; } // MerchantName public string MerchantBoss { get; set; } // MerchantBoss public string MerchantSex { get; set; } // MerchantSex public string MerchantTel { get; set; } // MerchantTel public string MerchantAdd { get; set; } // MerchantAdd public string MerchantId { get; set; } // MerchantId public string Feedback { get; set; } // Feedback public double Lon { get; set; } public double Lat { get; set; } public byte[] Logo { get; set; } public virtual ICollection<T_Promotion> TPromotions { get; set; } // T_Promotion.FK_T_Promotion_T_BaseInfo public virtual ICollection<T_Server> TServers { get; set; } // T_Server.FK_T_Server_T_BaseInfo public virtual T_Platform TPlatform { get; set; } // T_Platform.FK_T_Platform_T_BaseInfo public virtual T_MerchantType TMerchantType { get; set; } // FK_T_BaseInfo_T_MerchantType public virtual ICollection<T_DataInfo> TDataInfoes { get; set; } // T_DataInfo.FK_T_DataInfo_T_BaseInfo public T_BaseInfo() { TPromotions = new List<T_Promotion>(); TServers = new List<T_Server>(); } } }
需要注意的是这里的实体不能直接用于WCF服务(存在着主外键关系等),需要通过Mapper来转化为WCF服务能使用的实体
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.Text; namespace iTelluro.Explorer.YatMing.Application.DTO { [DataContract] public class TBaseInfoDTO { [DataMember] public string BaseInfoId { get; set; } [DataMember] public string MerchantName { get; set; } [DataMember] public string MerchantBoss { get; set; } [DataMember] public string MerchantSex { get; set; } [DataMember] public string MerchantTel { get; set; } [DataMember] public string MerchantAdd { get; set; } [DataMember] public string MerchantId { get; set; } [DataMember] public string Feedback { get; set; } [DataMember] public double Lon { get; set; } [DataMember] public double Lat { get; set; } [DataMember] public byte[] Logo { get; set; } } } Mapper.CreateMap<T_BaseInfo, TBaseInfoDTO>(); Mapper.CreateMap<TBaseInfoDTO, T_BaseInfo>();
3.业务逻辑层,主要是调用基础结构层的基础方法来构建业务所需要的逻辑。(代码生成工具已经提供了基础的增删改查)
using iTelluro.Explorer.YatMing.IApplication; using iTelluro.Explorer.YatMing.Application.DTO; using iTelluro.Explorer.Application.CodeFirst.Seedwork; using iTelluro.Explorer.Domain.CodeFirst.Seedwork; using System; using System.Collections.Generic; using System.Linq; using System.Text; using iTelluro.Explorer.YatMing.Domain.Context; using iTelluro.Explorer.YatMing.Domain.Entities; using iTelluro.Explorer.Infrastruct.CodeFirst.Seedwork; namespace iTelluro.Explorer.YatMing.Application { /// <summary> /// TBaseInfo基础方法的提供 /// </summary> public class TBaseInfoApp : ITBaseInfoApp { private ITBaseInfoRepository _repository; public TBaseInfoApp(ITBaseInfoRepository repository) { _repository = repository; } /// <summary> /// 新增一条TBaseInfo记录 /// </summary> /// <param name="dto">TBaseInfo实体</param> /// <returns>是否新增成功</returns> public bool Add(TBaseInfoDTO dto) { try { var entity = dto.ProjectedAs<T_BaseInfo>(); if (_repository.Insert(entity) > 0) { return true; } else { return false; } } catch (Exception ex) { throw ex; } } /// <summary> /// 根据主键删除一条TBaseInfo记录 /// </summary> /// <param name="guid">TBaseInfo主键值</param> /// <returns>是否删除成功</returns> public bool Remove(string guid) { try { if (_repository.Delete(guid) > 0) return true; else return false; } catch (Exception ex) { throw ex; } } /// <summary> /// 更新一条TBaseInfo记录 /// </summary> /// <param name="dto">TBaseInfo实体</param> /// <returns>是否更新成功</returns> public bool Update(TBaseInfoDTO dto) { try { if (_repository.Update(dto.ProjectedAs<T_BaseInfo>()) >= 0) return true; else return false; } catch (Exception ex) { throw ex; } } /// <summary> /// 根据TBaseInfo主键获取一条记录 /// </summary> /// <param name="guid">TBaseInfo主键值</param> /// <returns>根据主键查询到的TBaseInfo记录</returns> public TBaseInfoDTO Get(string guid) { try { var entity = _repository.GetByKey(guid); return entity.ProjectedAs<TBaseInfoDTO>(); } catch (Exception ex) { throw ex; } } /// <summary> /// 查询所有TBaseInfo记录 /// </summary> /// <returns>TBaseInfo所有记录集合</returns> public List<TBaseInfoDTO> GetAll() { try { return _repository.EntityNoTracking.ProjectedAsCollection<TBaseInfoDTO>(); } catch (Exception ex) { throw ex; } } public List<TBaseInfoDTO> QueryByKeyword(string key) { try { return _repository.EntityNoTracking.Where(t => t.MerchantName.Contains(key)).ProjectedAsCollection<TBaseInfoDTO>(); } catch (Exception ex) { throw ex; } } } }
4.服务层,通过调用业务层和实体层来为B/S或者C/S等客户端提供服务方法。
#region TBaseInfo /// <summary> /// 属性注入TBaseInfoApp /// </summary> [Dependency] public ITBaseInfoApp _TBaseInfoApp { get; set; } /// <summary> /// 新增一条TBaseInfo记录 /// </summary> /// <param name="TBaseInfoDTO">TBaseInfo实体</param> /// <returns>是否新增成功</returns> public bool TBaseInfoAdd(TBaseInfoDTO TBaseInfoDTO) { try { return _TBaseInfoApp.Add(TBaseInfoDTO); } catch (Exception ex) { ILog log = LogManager.GetLogger("YatMingSerice-" + this.GetType().Name + "-" + MethodBase.GetCurrentMethod().Name); log.Error(ex.Message); return false; } } /// <summary> /// 根据主键删除一条TBaseInfo记录 /// </summary> /// <param name="guid">主键值</param> /// <returns>是否删除成功</returns> public bool TBaseInfoDelete(string guid) { try { return _TBaseInfoApp.Remove(guid); } catch (Exception ex) { ILog log = LogManager.GetLogger("YatMingSerice-" + this.GetType().Name + "-" + MethodBase.GetCurrentMethod().Name); log.Error(ex.Message); return false; } } /// <summary> /// 更新一条TBaseInfo记录 /// </summary> /// <param name="TBaseInfoDTO">TBaseInfo实体</param> /// <returns>是否更新成功</returns> public bool TBaseInfoUpdate(TBaseInfoDTO TBaseInfoDTO) { try { return _TBaseInfoApp.Update(TBaseInfoDTO); } catch (Exception ex) { ILog log = LogManager.GetLogger("YatMingSerice-" + this.GetType().Name + "-" + MethodBase.GetCurrentMethod().Name); log.Error(ex.Message); return false; } } /// <summary> /// 根据主键查询一条TBaseInfo记录 /// </summary> /// <param name="guid">主键值</param> /// <returns>查询的实体结果</returns> public TBaseInfoDTO TBaseInfoQueryById(string guid) { try { return _TBaseInfoApp.Get(guid); } catch (Exception ex) { ILog log = LogManager.GetLogger("YatMingSerice-" + this.GetType().Name + "-" + MethodBase.GetCurrentMethod().Name); log.Error(ex.Message); return null; } } /// <summary> /// 查询所有的TBaseInfo记录 /// </summary> /// <returns>所有的TBaseInfo结果集</returns> public List<TBaseInfoDTO> TBaseInfoQueryAll() { try { return _TBaseInfoApp.GetAll(); } catch (Exception ex) { ILog log = LogManager.GetLogger("YatMingSerice-" + this.GetType().Name + "-" + MethodBase.GetCurrentMethod().Name); log.Error(ex.Message); return null; } } public List<TBaseInfoDTO> TBaseInfoQueryByKeyword(string key) { try { return _TBaseInfoApp.QueryByKeyword(key); } catch (Exception ex) { ILog log = LogManager.GetLogger("YatMingSerice-" + this.GetType().Name + "-" + MethodBase.GetCurrentMethod().Name); log.Error(ex.Message); return null; } } #endregion
3.总结
到这里整个基础的WCF服务环境就已经搭建完成了。可以通过IIS来使用发布的服务。或者直接本地调试服务。
项目已经发布到Github,可以前往签出
DDD生成工具模型解压放到D盘根目录就可以使用Entity2CodeModel