什么会导致Linq-to-SQL对象忽略新值

本文关键字:新值 对象 Linq-to-SQL 什么 | 更新日期: 2023-09-27 18:24:36

也许我遗漏了一些明显的东西,或者可能发生了一些险恶的事情,但这对我来说似乎很奇怪。我有一个Linq-to-SQL数据上下文,我正在尝试更新记录上的字段。更新不起作用,SQL事件探查器跟踪显示没有向数据库发出更新命令。因此,我缩小了代码的确切行数,并删除了各种变量,试图简化。

where子句不变的情况下,调试器中现在的情况如下:

var foo = db.f_pp_Budgets
            .Where(b => b.SeasonKey == seasonID)
            .Where(b => b.Business == businessUnit)
            .Where(b => b.Level == "R")
            .Where(b => b.CodeKey == region.Key)
            .Single().Trade;
// foo is now set to 1
db.f_pp_Budgets
            .Where(b => b.SeasonKey == seasonID)
            .Where(b => b.Business == businessUnit)
            .Where(b => b.Level == "R")
            .Where(b => b.CodeKey == region.Key)
            .Single().Trade = region.Budget.Trade;
// region.Budget.Trade was (and still is) 2
// so the underlying Linq to SQL object should have a 2 in it, right?
var baz = db.f_pp_Budgets
            .Where(b => b.SeasonKey == seasonID)
            .Where(b => b.Business == businessUnit)
            .Where(b => b.Level == "R")
            .Where(b => b.CodeKey == region.Key)
            .Single().Trade;
// baz is set to 1.  Shouldn't it be 2?

由于该值不变,因此调用db.SubmitChanges()自然不会向数据库发送任何内容。

有人能想到价值不会改变的原因吗?


更新代码:(回应@Hogan的回答)

var myObj = db.f_pp_Budgets
              .Where(b => b.SeasonKey == seasonID)
              .Where(b => b.Business == businessUnit)
              .Where(b => b.Level == "R")
              .Where(b => b.CodeKey == region.Key)
              .Single();
var foo = myObj.Trade;
// foo is now set to 1
myObj.Trade = region.Budget.Trade;
// region.Budget.Trade was (and still is) 2
var baz = myObj.Trade;
// baz is now set to 2

正在更新对象的值。但是,db.SubmitChanges()仍然没有向数据库发送任何update语句。

什么会导致Linq-to-SQL对象忽略新值

这个问题与作为等式的左值有关。也就是说,你不能先计算一个表达式,然后在c变体中赋值给它。

简单的答案,这样做:

 var myobj = db.f_pp_Budgets
        .Where(b => b.SeasonKey == seasonID)
        .Where(b => b.Business == businessUnit)
        .Where(b => b.Level == "R")
        .Where(b => b.CodeKey == region.Key)
        .Single();
myobj.Trade = region.Budget.Trade;

nb要理解为什么您的代码不起作用,请考虑以下两个非法分配:

 5+7 = 4
 obj.val + obj2.val = 4

发现问题。看起来System.Data.Linq.Table<>对象被设置为.IsReadOnly = true是因为基础表没有主键。这是有道理的,因为如果数据库中没有提供唯一标识符,Linq就没有可靠的方法来跟踪实体的唯一性。

人们希望为实体生成的代码可以在没有setter的情况下对受影响的类型生成属性,或者在设置时抛出异常。但事实并非如此,可能还有其他很好的原因,我对此一无所知。