如:我定义了一个EmployeeDao类,里面有很多操作数据库(增删改查)的方法。现在有一个问题让我纠结,就是声明一个DataContext属性好,还是在每一个方法里都New一下Datacontext好?
在实际的开发中,如果要声明一个DataContext,就得用单例模式,否则程序有时调用不同的DataContext,造成前台显示的结果与数据库不一致。
采用在每个方法里都New的方式,又担心因到处New会影响性能或漏洞,但因业务逻辑层中涉及到TanscationScope,统一有一个submitChanges()方法,而DataContext是做为参数传进去的,以避免因多个Connection 而升级到分布式事务。
请各位高手给点建议!
你这是一个问题吗?要回答这个可以写一本《Linq to SQL in Action》了。
基本上你都还知道每种方法都有优缺点,那就行了,每种都试试吧,反正又不会死的。
感谢回复,看来找到一个最优的设计模式是很难的。
@小学生Forever:
请问何为最优?只有场景最优,没有模式最优。
是6000元的iPhone6 Plus最优呢,
还是3299的小米最优?
或者是299元的Nokia 3255最优?
@爱编程的大叔: 最优就是既能实现TransationScope,又能不用反复New,还能从数据库得到实时数据,本人很菜的哟。
@小学生Forever: 菜你就用啥Transaction啊,没事找事吧。
菜的话,就用标准用法Using 每次new好了。
大叔所言既是,学习了!
@小学生Forever:
1、DataContext本身自带事务功能,一个SubmitChanges要么全部成功,要么全部失败。
2、事务这个你学学就好了,别当真,等你啥时候参加几百万上千万的软件项目时再用吧。普通人连软件都学不好怎么做呢,操心什么事务啊。
@爱编程的大叔: 大叔,您是前辈。问下,如果只是用linq查询数据库,输出结果后,DataContext会自动释放吗?之所以用到事务,是因为我要同时操作多个表。您推荐的《Linq In Action》真不错,我已下载,有些知识点正是我所需要的,谢谢。
@小学生Forever: 一般情况假设你是做的WEB编程。
1、view输出后DataContext一般就自动释放了。
2、同时操作多个表,也要看情况,普通情况下仍然是不需要事务的。
你要是有空,还是先认真看一看什么叫事务吧,为什么要使用事务?
看完了为什么,明白的话,通常大部份的人是不需要使用事务的。
3、你问的问题太泛以至于没有愿意解答。
@爱编程的大叔: 这是我的事务代码,请您看下有什么问题?
1 #region//保存 2 public int SaveFlowCardInfo(TFlowCardInfo obj ) 3 { 4 using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required)) 5 { 6 7 8 XingRuiDataBaseDataContext xrdc = new XingRuiDataBaseDataContext(); 9 if (obj.Content.ID != 0 && obj.Content.ID > 0) 10 { 11 FlowCardInfoContent content = dao.GetInfo(obj.Content.ID, xrdc); 12 if (content.AuditFlag == true) 13 { 14 throw new Exception("该单据已经审核" + content.FlowCardCode); 15 } 16 } 17 //投料数与产生的结果进行对比 18 19 ValidateFlowCardCounts(true, obj,xrdc); //验证数量 20 21 22 23 24 //更新流程卡数据库 25 dao.SaveFlowCardInfo(obj, xrdc); 26 27 28 # region //更新在制工序上的数量 29 30 31 List<WorkshopStoreGongXu> list = new List<WorkshopStoreGongXu>(); 32 foreach (var itm in obj.Detail) 33 { 34 WorkshopStoreGongXu gxsto = wkspstrgxdao.GetWorkshopStoreGongXu(obj.Content.PartCode, itm.DetDetail.gongxuname, xrdc); 35 36 if (gxsto == null)//库存中没有该货品 37 { 38 gxsto = new WorkshopStoreGongXu(); //创建库存表实例 39 40 gxsto.ProductCode = obj.Content.PartCode; 41 42 gxsto.Price = 0;// tPurDetail.DetDetail.Price; 43 gxsto.Amount = 0;//sto.Quantity * sto.Price; 44 45 gxsto.Quantity = itm.DetDetail.shengYuHeGeCount; 46 47 gxsto.ProductName = productinfodao.GetProductInfoByCode(obj.Content.PartCode).ProductName; 48 gxsto.Memo = ""; 49 gxsto.GongXuName = itm.DetDetail.gongxuname; 50 51 wkspstrgxdao.InsertInfo(gxsto, xrdc); //将该货品信息插入到库存表 52 53 } 54 else //库存中有该货品 55 { 56 gxsto.Quantity = gxsto.Quantity + itm.DetDetail.shengYuHeGeCount - itm.OldshengYuHeGeCount; 57 58 list.Add(gxsto); 59 60 } 61 62 } 63 wkspstrgxdao.UpdateInfoList(list, xrdc); 64 #endregion 65 66 67 68 69 #region //更新未加工库存 数量减少 70 71 72 WorkshopStoreNoProduce wkspsnpduce = wkspstnproducedao.GetWorkshopStoreNoProduce(obj.Content.PartCode, xrdc); 73 74 wkspsnpduce.Quantity = wkspsnpduce.Quantity - obj.Content.PartCount + obj.OldpartCount; 75 76 if (wkspsnpduce.Quantity < 0) 77 { 78 throw new Exception("库存不足!"); 79 } 80 81 wkspstnproducedao.UpdateInfo(wkspsnpduce, xrdc); 82 #endregion 83 84 xrdc.SubmitChanges(ConflictMode.FailOnFirstConflict); 85 86 87 88 ts.Complete(); 89 90 91 } 92 93 94 return 1; 95 } 96 97 #endregion
这段代码其实不用事务也可以,是不?有点明白您的意思了,最后一个submitChanges() 就是一个事务了,是不?
@小学生Forever:
1、这段代码确实没有必要用Transaction。
2、如果你不是存储过程黑的话,像这样的代码建议反正存储过程里面,可以减少很多的网络传输带宽。
我的做法是 建立一个container
contianer 里面存放所有的dataset
然后 container里面有一个commit方法
commit方法对这个container底下的所有 context 执行savechange
然后用事务套住这些savechange就好了 对外就公布一个commit方法
至于context 线程 唯一 每个线程里面有2个 dbcontext 分别做增删改操作 和查询操作
谢谢啦!