CSLA命令对象的简单封装
使用过CSLA的朋友们应该知道“命令对象”这个概念,它可以以多种方式使用,可以直接被用户界面代码所调用,以执行应用服务器上的任意代码,但更多的是被用在其他业务对象里面,以执行应用程序服务器上的代码。
最近在写命令对象的时候,遇到个问题不太好解决,所以想把思路写出来,让大家给分析下。问题描述:要求在浏览界面删除数据,而浏览界面只是为了让用户看到一些基本的信息,只做展示而已,所以用的是只读对象,这时如果要做删除就只能通过命令对象来做,可是每一个对象的删除操作都得写一个命令对象,而它们之间的差异也就是对象不同而已,所以想把这个不同提取出来作为条件传进去以简化代码,例如删除文章和广告这两个对象的命令对象代码如下:
[Serializable] public class cmdDeleteArticle : Csla.CommandBase { private List<string> _uniqueIds; private cmdDeleteArticle() { } private cmdDeleteArticle(List<string> uniqueIDs) { _uniqueIds = uniqueIDs; } #region Factory Methods public static void DeleteArticle(List<string> uniqueIDs) { var cmd = new cmdDeleteArticle(uniqueIDs); cmd = DataPortal.Execute<cmdDeleteArticle>(cmd); } #endregion //Factory Methods #region Data Access protected override void DataPortal_Execute() { using (var mgr = ContextManager<EasyBridge.DataAccess.ebSynDataContext> .GetManager(EasyBridge.DataAccess.Database.EasyBridgeSyn)) { foreach (string uniqueId in _uniqueIds) { try { var article = mgr.DataContext.Articles.SingleOrDefault(p => p.UniqueID == uniqueId); if (article != null) { mgr.DataContext.Articles.DeleteOnSubmit(article); } mgr.DataContext.SubmitChanges(); } catch (Exception ex) { throw new Exception(ex.Message); } } } } #endregion //Data Access }
[Serializable] public class cmdDeleteAdvert : Csla.CommandBase { private List<string> _uniqueIds; private cmdDeleteAdvert() { } private cmdDeleteAdvert(List<string> uniqueIDs) { _uniqueIds = uniqueIDs; } #region Factory Methods public static void DeleteAdvert(List<string> uniqueIDs) { var cmd = new cmdDeleteAdvert(uniqueIDs); cmd = DataPortal.Execute<cmdDeleteAdvert>(cmd); } #endregion //Factory Methods #region Data Access protected override void DataPortal_Execute() { using (var mgr = ContextManager<EasyBridge.DataAccess.ebSynDataContext> .GetManager(EasyBridge.DataAccess.Database.EasyBridgeSyn)) { foreach (string uniqueId in _uniqueIds) { try { var advert = mgr.DataContext.Adverts.SingleOrDefault(p => p.UniqueID == uniqueId); if (advert != null) { mgr.DataContext.Adverts.DeleteOnSubmit(advert); } mgr.DataContext.SubmitChanges(); } catch (Exception ex) { throw new Exception(ex.Message); } } } } #endregion //Data Access }
可以看出,代码中除了数据上下文的表不同并无其他差异:因此,我想构造一个基类,简单封装一下这个变化。基类构造如下:
[Serializable] public class cmdDeleteBase<T> : Csla.CommandBase where T : Type { private List<string> _uniqueIDs; private System.Data.Linq.Table<T> _tables; private cmdDeleteBase() { } private cmdDeleteBase(List<string> uniqueIDs, System.Data.Linq.Table<T> tables) { _uniqueIDs = uniqueIDs; _tables = tables; } #region Factory Methods public virtual static void DeleteRecord(List<string> uniqueIDs, System.Data.Linq.Table<T> tables) { var cmd = new cmdDeleteBase<T>(uniqueIDs, tables); cmd = DataPortal.Execute<cmdDeleteBase<T>>(cmd); } #endregion #region Data Access protected override void DataPortal_Execute() { using (var mgr = ContextManager<EasyBridge.DataAccess.ebSynDataContext> .GetManager(EasyBridge.DataAccess.Database.EasyBridgeSyn)) { foreach (string uniqueID in _uniqueIDs) { try { var businessObject = mgr.DataContext.GetTable<T>().SingleOrDefault(p => p.UniqueID == uniqueID); if (businessObject != null) { mgr.DataContext.GetTable<T>().DeleteOnSubmit(businessObject); } mgr.DataContext.SubmitChanges(); } catch (Exception ex) { throw new Exception(ex.Message); } } } } #endregion //Data Access }
现在有几个问题:
1. 用泛型的话,那个Type没法确定,因为LINQ2SQL生成的类没有基类
[Table(Name="dbo.Article")]
public partial class Article : INotifyPropertyChanging, INotifyPropertyChanged
2. T 确定不了 那个 p => p.UniqueID == uniqueID 就推断出来
【天天来(http://www.daydaycome.com)】- 精选折扣商品,爆料精选,九块九白菜底价尽在天天来!是一个中立的,致力于帮助广大网友买到更有性价比网购产品的分享平台,每天为网友们提供最受追捧 最具性价比 最大幅降价潮流新品资讯。我们的信息大部分来自于网友爆料,如果您发现了优质的产品或好的价格,不妨给我们爆料(谢绝商家)