gpt4 book ai didi

C# LINQ-TO-SQL : datacontext. ChangeConflicts 未显示所有冲突

转载 作者:太空宇宙 更新时间:2023-11-03 14:18:53 25 4
gpt4 key购买 nike

我在使用 linq-to-sql 并尝试解决冲突时遇到了问题。问题是有时没有检测到冲突。请看下面的代码示例:

// Setup the object to re-produce the problem
//
// MyObject has properties: id, my_string, my_int and version (timestamp) to enable
// conflicts detection
var context = new MyDataContext();
var obj = new MyObject();
obj.id = "1";
obj.my_string = "value";
obj.my_int = 0;
context.MyTable.InsertOnSubmit(obj);
context.SubmitChanges();
context.dispose();

// Get 2 data contexts
var context1 = new MyDataContext();
var context2 = new MyDataContext();

// Get 2 instances of obj - 1 from each context
var obj1= context1.MyTable.SingleOrDefault(o => o.id == "1");
var obj2= context2.MyTable.SingleOrDefault(o => o.id == "1");

// Change the values of obj1 and update it to the database
obj1.my_string= "value1";
obj1.my_int= 0;
context1.SubmitChanges();
context1.Dispose();

// Update the changes in obj2
obj2.my_string= "value2";
obj2.my_int= 1;

// Now the database contains:
// id: "1"
// my_string: "value1"
// my_int: 0

// obj2 contains:
// id: "1"
// my_string: "value2"
// my_int: 1

try
{
context2.SubmitChanges();
}
catch(ChangeConflictException ex)
{
LogInfo("Conflicting members:");
context2.ChangeConflicts[0].MemberConflicts.ToList().ForEach(
mcc=>LogInfo("Property '{0}': Database value: {1}, Current Value:{2}", mcc.Member.Name, mcc.DatabaseValue, mcc.CurrentValue)
);
}
context2.Dispose();

在 catch 中,我希望看到 3 个成员冲突:my_string、my_int 和 version,但我只看到 2 个成员冲突:my_string 和 version。 my_int 未被检测为冲突。

如果我在创建对象时将 my_int 设置为与我分配给 obj2 的值不同的值,则会检测到冲突。

我发现了一些共同点:当原始对象的某个属性(任何属性)的值等于obj1的值时,不会检测到该属性的冲突。

我想知道如何解决这个问题,以便成功检测到冲突

最佳答案

我找到了问题的根本原因。我没有得到“my_int”属性冲突的原因是因为它与 context2“知道”的数据库值不冲突。我将对此进行解释:

我认为冲突定义为当保存的对象的值不等于数据库中的值时这不是!!!!!!

冲突定义为数据库中的当前值不等于上下文熟悉的原始值。原始值是执行选择查询时数据库中的值。

检查我问题中的示例,当 context2 从数据库中选择数据来创建 obj2 时,proeprties 值为:my_string: "value", my_int:0。这些是原始值。

当我尝试保存数据时,LINQ-TO-SQL 将原始值与数据库值进行比较。此时的数据库值(保存obj1后):my_string: "value1", my_int:0

结果,我在 my_string (original: "value", database:"value1") 中遇到了冲突,但在 my_int(original: 0, database: 0) 中没有。

发现这一点帮助我理解了为什么没有冲突,但仍然没有帮助我解决问题,因为错误的值没有保存到数据库中,因为我只分析了 ObjectChangeConflict 中存在的 MemberChangeConflicts,如果我正在检查的属性在那里不存在,检查逻辑被跳过。

解决方案是分析修改后的可枚举成员,这些成员可以访问所有修改过的属性,对于每个成员我可以获得原始值和新值。

要获取修改后的成员,需要执行名为 GetModifiedMembers 的方法。该方法在object数据类型表中,执行如下:

 var mmc = context.MyTable.GetModifiedMembers(myobject);

结合冲突和修改后的成员,我可以全面了解导致冲突的对象所发生的情况并妥善处理。

感谢 Damien_The_Unbeliever 在他的评论中给出提示。

关于C# LINQ-TO-SQL : datacontext. ChangeConflicts 未显示所有冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5925791/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com