这是从客户端A插入新记录到服务器时:
var Invoice = new Invoice();
foreach (DataGridViewRow item in DataGridView1.Rows)
{
Invoice.InvoiceDetails.Add(new InvoiceDetail
{
Description = txt1.Text,
TotalPrice = txt2.Text
});
}
dc.Invoices.InsertOnSubmit(Invoice);
dc.SubmitChanges();
好的,现在想象客户端2将编辑此记录。
var Invoice = dc.Invoices.First(p => p.ID == _InvoiceID);
dc.InvoiceDetails.DeleteAllOnSubmit(Invoice.InvoiceDetails);
foreach (DataGridViewRow item in DataGridView1.Rows)
{
Invoice.InvoiceDetails.Add(new InvoiceDetail
{
Description = "Description",
TotalPrice = "10000000"
});
}
dc.SubmitChanges();
现在就是这个东西。客户端有前2个发票,IT插入自己仍然驻留在其DataClass中。
这意味着两个客户端在RAM上有两个不同的DataClasses Localy。
当客户端1再次进行另一次编辑时,问题开始:
使用以下方法再次选择发票时:
var Invoice = dc.Invoices.First(p => p.ID == _InvoiceID);
目前客户端1上的这张发票有2个它自己添加到数据库,仍然在它的dc.so上,这个选择它也会从客户端2从服务器添加的数据库中添加2。
所以问题是客户端1将显示4个详细信息而不是2个,包含来自服务器系统的2个,以及来自其本地DataClass的2个。
我刚刚得知其称为数据并发
请注意,数据上下文是静态的和公共的,并且在整个应用程序生命周期中保持活动状态。我知道这是错误的,必须保持简短但数据量很大,我不能在每个表单上创建一个新的数据上下文。
寻找解决方案,因为我已经切换到修复的实体框架,但我需要应用解决方案到应用程序的当前状态,直到我完成切换到实体框架。
还有一件事,应用程序创建了它的数据库,因此sprocs不是一个选项,因为t linq无法使用createdatabase()创建em。
答案 0 :(得分:2)
如果您根据需要实例化DataContext,则可以阻止它过时:
using (Entities dc = new Entities())
{
var Invoice = dc.Invoices.First(p => p.ID == _InvoiceID);
dc.InvoiceDetails.DeleteAllOnSubmit(Invoice.InvoiceDetails);
foreach (DataGridViewRow item in DataGridView1.Rows)
{
Invoice.InvoiceDetails.Add(new InvoiceDetail
{
Description = "Description",
TotalPrice = "10000000"
});
}
dc.SubmitChanges();
}
对于某些背景,请参阅,例如:
Instantiating a context in LINQ to Entities
关于静态DbContext
的解释后编辑另一种方法是将所有SQL放在存储过程中,用于两个客户端;那么你不依赖于DbContext的状态。