首页 新闻 会员 周边 捐助

各位高手,问一个关于Linq To Sql 模式下数据访问层设计的问题,DataContext的定义在哪里好?

0
[已解决问题] 解决于 2015-04-17 12:47

如:我定义了一个EmployeeDao类,里面有很多操作数据库(增删改查)的方法。现在有一个问题让我纠结,就是声明一个DataContext属性好,还是在每一个方法里都New一下Datacontext好?

在实际的开发中,如果要声明一个DataContext,就得用单例模式,否则程序有时调用不同的DataContext,造成前台显示的结果与数据库不一致。

采用在每个方法里都New的方式,又担心因到处New会影响性能或漏洞,但因业务逻辑层中涉及到TanscationScope,统一有一个submitChanges()方法,而DataContext是做为参数传进去的,以避免因多个Connection 而升级到分布式事务。

请各位高手给点建议!

小学生Forever的主页 小学生Forever | 菜鸟二级 | 园豆:206
提问于:2015-04-06 15:03
< >
分享
最佳答案
0

你这是一个问题吗?要回答这个可以写一本《Linq to SQL in Action》了。

基本上你都还知道每种方法都有优缺点,那就行了,每种都试试吧,反正又不会死的。

奖励园豆:5
爱编程的大叔 | 高人七级 |园豆:30844 | 2015-04-06 15:42

感谢回复,看来找到一个最优的设计模式是很难的。

小学生Forever | 园豆:206 (菜鸟二级) | 2015-04-06 16:21

@小学生Forever:

请问何为最优?只有场景最优,没有模式最优。

是6000元的iPhone6 Plus最优呢,

还是3299的小米最优?

或者是299元的Nokia 3255最优?

爱编程的大叔 | 园豆:30844 (高人七级) | 2015-04-06 16:25

@爱编程的大叔: 最优就是既能实现TransationScope,又能不用反复New,还能从数据库得到实时数据,本人很菜的哟。

小学生Forever | 园豆:206 (菜鸟二级) | 2015-04-06 16:29

@小学生Forever: 菜你就用啥Transaction啊,没事找事吧。

菜的话,就用标准用法Using 每次new好了。

爱编程的大叔 | 园豆:30844 (高人七级) | 2015-04-06 16:33

大叔所言既是,学习了!

小学生Forever | 园豆:206 (菜鸟二级) | 2015-04-06 16:38

@小学生Forever:

1、DataContext本身自带事务功能,一个SubmitChanges要么全部成功,要么全部失败。

2、事务这个你学学就好了,别当真,等你啥时候参加几百万上千万的软件项目时再用吧。普通人连软件都学不好怎么做呢,操心什么事务啊。

爱编程的大叔 | 园豆:30844 (高人七级) | 2015-04-06 16:53

@爱编程的大叔: 大叔,您是前辈。问下,如果只是用linq查询数据库,输出结果后,DataContext会自动释放吗?之所以用到事务,是因为我要同时操作多个表。您推荐的《Linq In Action》真不错,我已下载,有些知识点正是我所需要的,谢谢。

小学生Forever | 园豆:206 (菜鸟二级) | 2015-04-06 17:18

@小学生Forever: 一般情况假设你是做的WEB编程。

1、view输出后DataContext一般就自动释放了。

2、同时操作多个表,也要看情况,普通情况下仍然是不需要事务的。

你要是有空,还是先认真看一看什么叫事务吧,为什么要使用事务?

看完了为什么,明白的话,通常大部份的人是不需要使用事务的。

3、你问的问题太泛以至于没有愿意解答。

爱编程的大叔 | 园豆:30844 (高人七级) | 2015-04-06 17:42

@爱编程的大叔: 这是我的事务代码,请您看下有什么问题?

 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 | 园豆:206 (菜鸟二级) | 2015-04-06 18:24

@小学生Forever: 

1、这段代码确实没有必要用Transaction。

2、如果你不是存储过程黑的话,像这样的代码建议反正存储过程里面,可以减少很多的网络传输带宽。

爱编程的大叔 | 园豆:30844 (高人七级) | 2015-04-07 12:43
其他回答(1)
0

我的做法是 建立一个container

contianer 里面存放所有的dataset

然后 container里面有一个commit方法

commit方法对这个container底下的所有 context 执行savechange

然后用事务套住这些savechange就好了 对外就公布一个commit方法

 

至于context 线程 唯一 每个线程里面有2个 dbcontext 分别做增删改操作 和查询操作

小眼睛老鼠 | 园豆:2731 (老鸟四级) | 2015-04-07 17:52

谢谢啦!

支持(0) 反对(0) 小学生Forever | 园豆:206 (菜鸟二级) | 2015-04-17 12:45
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册