是什么导致Linq to SQL对象忽略新值?

时间:2012-02-15 14:56:27

标签: c# linq-to-sql

也许我错过了一些明显的东西,或者可能发生了一些险恶的事情,但这对我来说似乎很奇怪。我有一个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's answer

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语句。

2 个答案:

答案 0 :(得分:1)

这个问题与左值作为方程式有关。那就是你不能评估一个表达式然后用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;

要了解您的代码无效的原因,请考虑以下两个非法分配:

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

答案 1 :(得分:0)

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

人们希望生成的实体代码可以在没有setter的情况下在受影响的类型上创建属性,或者在设置时抛出异常。但可能有其他充分理由说明为什么不是这种情况,我不知道。