环境:.net4.6+csla4.6
实现:对象的数据库访问及数据库执行使用Factory方式进行封闭。
正文:
以前在使用csla框架完成业务对象的定义时所有的数据处理都在对象内部实现,也不能说不好,对象很大。作者给了通过Factory的方式将对象的数据访问层进行分离,代码更容易维护。以下是我通过Factory的方式实现对象数据访问。
首先是通过csla的约定定义业务对象,其中包含了属性验证:
1 [Serializable] 2 [Csla.Server.ObjectFactory("HFunM.Business.Service.CustomDevelop.AssetManage.CategoriesService, HFunM.Business.Service", "CreateCategory", "FetchCategory", "UpdateCategory", "DeleteCategory")] 3 public class Asset_CategoryER : Csla.BusinessBase<Asset_CategoryER> 4 { 5 #region Contructor 6 7 public Asset_CategoryER() 8 { /* Require use of factory methods */ } 9 10 #endregion 11 12 #region Properties 13 14 public static readonly PropertyInfo<System.String> _actIdProperty 15 = RegisterProperty<System.String>(p => p.ActId, "主键ID"); 16 /// <summary> 17 /// 主键ID 18 /// </summary> 19 [System.ComponentModel.DataObjectField(true, false)] 20 public System.String ActId 21 { 22 get { return GetProperty(_actIdProperty); } 23 set { SetProperty(_actIdProperty, value); } 24 } 25 26 public static readonly PropertyInfo<System.String> _aCTParentIDProperty 27 = RegisterProperty<System.String>(p => p.ACTParentID, "上级分类ID", (System.String)null); 28 /// <summary> 29 /// 上级分类ID 30 /// </summary> 31 public System.String ACTParentID 32 { 33 get { return GetProperty(_aCTParentIDProperty); } 34 set { SetProperty(_aCTParentIDProperty, value); } 35 } 36 37 public static readonly PropertyInfo<System.String> _aCTSysCodeProperty 38 = RegisterProperty<System.String>(p => p.ACTSysCode, "系统分类编号", (System.String)null); 39 /// <summary> 40 /// 系统分类编号 41 /// </summary> 42 public System.String ACTSysCode 43 { 44 get { return GetProperty(_aCTSysCodeProperty); } 45 set { SetProperty(_aCTSysCodeProperty, value); } 46 } 47 48 public static readonly PropertyInfo<System.String> _aCTNameProperty 49 = RegisterProperty<System.String>(p => p.ACTName, "分类名称", (System.String)null); 50 /// <summary> 51 /// 分类名称 52 /// </summary> 53 public System.String ACTName 54 { 55 get { return GetProperty(_aCTNameProperty); } 56 set { SetProperty(_aCTNameProperty, value); } 57 } 58 59 public static readonly PropertyInfo<System.String> _aCTShortNameProperty 60 = RegisterProperty<System.String>(p => p.ACTShortName, "名称缩写", (System.String)null); 61 /// <summary> 62 /// 名称缩写 63 /// </summary> 64 public System.String ACTShortName 65 { 66 get { return GetProperty(_aCTShortNameProperty); } 67 set { SetProperty(_aCTShortNameProperty, value); } 68 } 69 70 public static readonly PropertyInfo<System.String> _aCTStateProperty 71 = RegisterProperty<System.String>(p => p.ACTState, "分类状态", (System.String)null); 72 /// <summary> 73 /// 分类状态 74 /// </summary> 75 public System.String ACTState 76 { 77 get { return GetProperty(_aCTStateProperty); } 78 set { SetProperty(_aCTStateProperty, value); } 79 } 80 81 public static readonly PropertyInfo<System.Int32?> _aCTServiceLifeProperty 82 = RegisterProperty<System.Int32?>(p => p.ACTServiceLife, "使用年限", (System.Int32?)null); 83 /// <summary> 84 /// 使用年限 85 /// </summary> 86 public System.Int32? ACTServiceLife 87 { 88 get { return GetProperty(_aCTServiceLifeProperty); } 89 set { SetProperty(_aCTServiceLifeProperty, value); } 90 } 91 92 public static readonly PropertyInfo<System.Double?> _aCTSalvageRateProperty 93 = RegisterProperty<System.Double?>(p => p.ACTSalvageRate, "残值率(%)", (System.Double?)null); 94 /// <summary> 95 /// 残值率(%) 96 /// </summary> 97 public System.Double? ACTSalvageRate 98 { 99 get { return GetProperty(_aCTSalvageRateProperty); } 100 set { SetProperty(_aCTSalvageRateProperty, value); } 101 } 102 103 public static readonly PropertyInfo<System.String> _aCTUnitProperty 104 = RegisterProperty<System.String>(p => p.ACTUnit, "计算单位", (System.String)null); 105 /// <summary> 106 /// 计算单位 107 /// </summary> 108 public System.String ACTUnit 109 { 110 get { return GetProperty(_aCTUnitProperty); } 111 set { SetProperty(_aCTUnitProperty, value); } 112 } 113 114 public static readonly PropertyInfo<System.String> _aCTRemarkProperty 115 = RegisterProperty<System.String>(p => p.ACTRemark, "备注", (System.String)null); 116 /// <summary> 117 /// 备注 118 /// </summary> 119 public System.String ACTRemark 120 { 121 get { return GetProperty(_aCTRemarkProperty); } 122 set { SetProperty(_aCTRemarkProperty, value); } 123 } 124 125 public static readonly PropertyInfo<System.String> _aCTVoucherProperty 126 = RegisterProperty<System.String>(p => p.ACTVoucher, "会计凭证号", (System.String)null); 127 /// <summary> 128 /// 会计凭证号 129 /// </summary> 130 public System.String ACTVoucher 131 { 132 get { return GetProperty(_aCTVoucherProperty); } 133 set { SetProperty(_aCTVoucherProperty, value); } 134 } 135 136 #endregion 137 138 #region Business Rules 139 140 /// <summary> 141 /// Contains the CodeSmith generated validation rules. 142 /// </summary> 143 protected override void AddBusinessRules() 144 { 145 // Call the base class, if this call isn‘t made than any declared System.ComponentModel.DataAnnotations rules will not work. 146 base.AddBusinessRules(); 147 148 BusinessRules.AddRule(new Csla.Rules.CommonRules.Required(_actIdProperty)); 149 BusinessRules.AddRule(new Csla.Rules.CommonRules.Required(_aCTNameProperty)); 150 BusinessRules.AddRule(new Csla.Rules.CommonRules.Required(_aCTParentIDProperty)); 151 BusinessRules.AddRule(new Csla.Rules.CommonRules.Required(_aCTSysCodeProperty)); 152 BusinessRules.AddRule(new Csla.Rules.CommonRules.MaxLength(_actIdProperty, 36)); 153 BusinessRules.AddRule(new Csla.Rules.CommonRules.MaxLength(_aCTParentIDProperty, 36)); 154 BusinessRules.AddRule(new Csla.Rules.CommonRules.MaxLength(_aCTSysCodeProperty, 50)); 155 BusinessRules.AddRule(new Csla.Rules.CommonRules.MaxLength(_aCTNameProperty, 50)); 156 BusinessRules.AddRule(new Csla.Rules.CommonRules.MaxLength(_aCTShortNameProperty, 50)); 157 BusinessRules.AddRule(new Csla.Rules.CommonRules.MaxLength(_aCTStateProperty, 20)); 158 BusinessRules.AddRule(new Csla.Rules.CommonRules.MaxLength(_aCTUnitProperty, 20)); 159 BusinessRules.AddRule(new Csla.Rules.CommonRules.MaxLength(_aCTRemarkProperty, 200)); 160 BusinessRules.AddRule(new Csla.Rules.CommonRules.MaxLength(_aCTVoucherProperty, 50)); 161 } 162 163 #endregion 164 165 #region Factory 166 167 public static Asset_CategoryER NewCategory(string parentID) 168 { 169 return DataPortal.Create<Asset_CategoryER>(parentID); 170 } 171 172 public static Asset_CategoryER GetCategory(string id) 173 { 174 return DataPortal.Fetch<Asset_CategoryER>(id); 175 } 176 177 public static void DeleteCategory(string id) 178 { 179 DataPortal.Delete<Asset_CategoryER>(id); 180 } 181 182 #endregion 183 }
可能已经发现了属性Csla.Server.ObjectFactoryAttribute,它就是定义Factory的,其中提供了多种构造方式,如下:
1 namespace Csla.Server 2 { 3 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)] 4 public class ObjectFactoryAttribute : Attribute 5 { 6 public ObjectFactoryAttribute(string factoryType); 7 public ObjectFactoryAttribute(Type factoryType); 8 public ObjectFactoryAttribute(string factoryType, string fetchMethod); 9 public ObjectFactoryAttribute(Type factoryType, string fetchMethod); 10 public ObjectFactoryAttribute(string factoryType, string createMethod, string fetchMethod); 11 public ObjectFactoryAttribute(Type factoryType, string createMethod, string fetchMethod); 12 public ObjectFactoryAttribute(string factoryType, string createMethod, string fetchMethod, string updateMethod, string deleteMethod); 13 public ObjectFactoryAttribute(Type factoryType, string createMethod, string fetchMethod, string updateMethod, string deleteMethod); 14 public ObjectFactoryAttribute(string factoryType, string createMethod, string fetchMethod, string updateMethod, string deleteMethod, string executeMethod); 15 public ObjectFactoryAttribute(Type factoryType, string createMethod, string fetchMethod, string updateMethod, string deleteMethod, string executeMethod); 16 17 public string FactoryTypeName { get; } 18 public string CreateMethodName { get; } 19 public string FetchMethodName { get; } 20 public string UpdateMethodName { get; } 21 public string DeleteMethodName { get; } 22 public string ExecuteMethodName { get; } 23 } 24 }
以下是Factory的数据访问实现:
1 public class CategoriesService : Data.Repository.RepositoryFactory<Entity.CustomDevelop.AssetEntity.Asset_CategoryEntity> 2 { 3 #region 列表 4 5 /// <summary> 6 /// 加载所有数据 7 /// </summary> 8 /// <returns></returns> 9 public Asset_CategoryList FetchList() 10 { 11 var obj = (Asset_CategoryList)MethodCaller.CreateInstance(typeof(Asset_CategoryList)); 12 var rlce = obj.RaiseListChangedEvents; 13 obj.RaiseListChangedEvents = false; 14 base.SetIsReadOnly(obj, false); 15 16 var child = base.BaseRepository().IQueryable(p => p.ACT_State == "1"); 17 foreach (var item in child) 18 { 19 obj.Add(CreateItem(item)); 20 } 21 22 base.SetIsReadOnly(obj, true); 23 obj.RaiseListChangedEvents = rlce; 24 return obj; 25 } 26 27 /// <summary> 28 /// 创建列表子对象 29 /// </summary> 30 /// <returns></returns> 31 public Asset_CategoryInfo CreateItem() 32 { 33 var obj = (Asset_CategoryInfo)MethodCaller.CreateInstance(typeof(Asset_CategoryInfo)); 34 LoadProperty(obj, Asset_CategoryInfo._actIdProperty, Util.CommonHelper.GetGuid); 35 MarkNew(obj); 36 CheckRules(obj); 37 return obj; 38 } 39 40 /// <summary> 41 /// 42 /// </summary> 43 /// <param name="et"></param> 44 /// <returns></returns> 45 public Asset_CategoryInfo CreateItem(Entity.CustomDevelop.AssetEntity.Asset_CategoryEntity et) 46 { 47 var obj = (Asset_CategoryInfo)MethodCaller.CreateInstance(typeof(Asset_CategoryInfo)); 48 MarkAsChild(obj); 49 50 LoadProperty(obj, Asset_CategoryInfo._actIdProperty, et.ACT_ID); 51 LoadProperty(obj, Asset_CategoryInfo._aCTNameProperty, et.ACT_Name); 52 LoadProperty(obj, Asset_CategoryInfo._aCTParentIDProperty, et.ACT_ParentID); 53 LoadProperty(obj, Asset_CategoryInfo._aCTRemarkProperty, et.ACT_Remark); 54 LoadProperty(obj, Asset_CategoryInfo._aCTSalvageRateProperty, et.ACT_SalvageRate); 55 LoadProperty(obj, Asset_CategoryInfo._aCTServiceLifeProperty, et.ACT_ServiceLife); 56 LoadProperty(obj, Asset_CategoryInfo._aCTShortNameProperty, et.ACT_ShortName); 57 LoadProperty(obj, Asset_CategoryInfo._aCTStateProperty, et.ACT_State); 58 LoadProperty(obj, Asset_CategoryInfo._aCTSysCodeProperty, et.ACT_SysCode); 59 LoadProperty(obj, Asset_CategoryInfo._aCTUnitProperty, et.ACT_Unit); 60 LoadProperty(obj, Asset_CategoryInfo._aCTVoucherProperty, et.ACT_Voucher); 61 62 MarkOld(obj); 63 return obj; 64 } 65 66 #endregion 67 68 #region 主对象 69 70 /// <summary> 71 /// 创建类别 72 /// </summary> 73 /// <returns></returns> 74 public Asset_CategoryER CreateCategory(string parentID) 75 { 76 var obj = (Asset_CategoryER)MethodCaller.CreateInstance(typeof(Asset_CategoryER)); 77 LoadProperty(obj, Asset_CategoryER._actIdProperty, Util.CommonHelper.GetGuid); 78 LoadProperty(obj, Asset_CategoryER._aCTParentIDProperty, parentID); 79 MarkNew(obj); 80 CheckRules(obj); 81 return obj; 82 } 83 84 /// <summary> 85 /// 加载类别 86 /// </summary> 87 /// <param name="id">类别ID</param> 88 /// <returns></returns> 89 public Asset_CategoryER FetchCategory(string id) 90 { 91 var et = base.BaseRepository().FindEntity(id); 92 if (et != null) 93 { 94 var obj = (Asset_CategoryER)MethodCaller.CreateInstance(typeof(Asset_CategoryER)); 95 LoadProperty(obj, Asset_CategoryER._actIdProperty, et.ACT_ID); 96 LoadProperty(obj, Asset_CategoryER._aCTNameProperty, et.ACT_Name); 97 LoadProperty(obj, Asset_CategoryER._aCTParentIDProperty, et.ACT_ParentID); 98 LoadProperty(obj, Asset_CategoryER._aCTRemarkProperty, et.ACT_Remark); 99 LoadProperty(obj, Asset_CategoryER._aCTSalvageRateProperty, et.ACT_SalvageRate); 100 LoadProperty(obj, Asset_CategoryER._aCTServiceLifeProperty, et.ACT_ServiceLife); 101 LoadProperty(obj, Asset_CategoryER._aCTShortNameProperty, et.ACT_ShortName); 102 LoadProperty(obj, Asset_CategoryER._aCTStateProperty, et.ACT_State); 103 LoadProperty(obj, Asset_CategoryER._aCTSysCodeProperty, et.ACT_SysCode); 104 LoadProperty(obj, Asset_CategoryER._aCTUnitProperty, et.ACT_Unit); 105 LoadProperty(obj, Asset_CategoryER._aCTVoucherProperty, et.ACT_Voucher); 106 107 MarkOld(obj); 108 CheckRules(obj); 109 return obj; 110 } 111 else 112 { 113 return null; 114 } 115 } 116 117 /// <summary> 118 /// 更新类别 119 /// </summary> 120 /// <param name="obj">更新对象</param> 121 /// <returns></returns> 122 public Asset_CategoryER UpdateCategory(Asset_CategoryER obj) 123 { 124 if (obj.IsDeleted) 125 { 126 if (!obj.IsNew) 127 { 128 //旧对象,删除 129 DeleteCategory(obj.ActId); 130 } 131 //创建新的 132 MarkNew(obj); 133 } 134 else 135 { 136 CheckRules(obj); 137 if (!obj.IsSavable) 138 { 139 throw new Csla.Rules.ValidationException(obj.BrokenRulesCollection.ToString()); 140 } 141 if (obj.IsNew) 142 { 143 //创建 144 Entity.CustomDevelop.AssetEntity.Asset_CategoryEntity entity = new Entity.CustomDevelop.AssetEntity.Asset_CategoryEntity(); 145 entity.ACT_ID = obj.ActId; 146 entity.ACT_Name = obj.ACTName; 147 entity.ACT_ParentID = obj.ACTParentID; 148 entity.ACT_Remark = obj.ACTRemark; 149 entity.ACT_SalvageRate = obj.ACTSalvageRate; 150 entity.ACT_ServiceLife = obj.ACTServiceLife; 151 entity.ACT_ShortName = obj.ACTShortName; 152 entity.ACT_State = obj.ACTState; 153 entity.ACT_SysCode = obj.ACTSysCode; 154 entity.ACT_Unit = obj.ACTUnit; 155 entity.ACT_Voucher = obj.ACTVoucher; 156 157 base.BaseRepository().Insert(entity); 158 } 159 else 160 { 161 //更新 162 var entity = base.BaseRepository().FindEntity(obj.ActId); 163 entity.ACT_Name = obj.ACTName; 164 entity.ACT_ParentID = obj.ACTParentID; 165 entity.ACT_Remark = obj.ACTRemark; 166 entity.ACT_SalvageRate = obj.ACTSalvageRate; 167 entity.ACT_ServiceLife = obj.ACTServiceLife; 168 entity.ACT_ShortName = obj.ACTShortName; 169 entity.ACT_State = obj.ACTState; 170 entity.ACT_SysCode = obj.ACTSysCode; 171 entity.ACT_Unit = obj.ACTUnit; 172 entity.ACT_Voucher = obj.ACTVoucher; 173 174 base.BaseRepository().Update(entity); 175 } 176 MarkOld(obj); 177 } 178 return obj; 179 } 180 181 public void DeleteCategory(string id) 182 { 183 base.BaseRepository().Delete(id); 184 } 185 186 #endregion 187 }
数据的访问是通过EF实现,通过定义数据访问基类,承载了EF的访问接口以及csla框架提供的ObjectFactory:
1 public class RepositoryFactory<T> : Csla.Server.ObjectFactory 2 where T : class, new()
以上即实现的Csla业务对象及其数据访问对象,其他类型的如列表对象等都可以通过该方式实现。
欢迎转载,请留标记《HFun.net快速开发平台》
时间: 2024-10-30 00:29:26