系统:sql2005+vs2008
我有一个商品档案表SPDA,主键为条码TM,当TM输入错误时,过后可以修改。程序如下:
IEnumerable<SPDA> pmatches = from p in db.SPDA
where p.TM == TM_OLD    
select p;
 foreach(SPDA p in pmatches)
{            
  p.TM = tmName.Text;
  p.TMJG = decimal.Parse(tbPrice.Text.Trim());
  db.SubmitChanges();
}
执行到db.SubmitChanges();时错误提示为:
“类型为“SPDA”的对象的成员“TM”的值已更改。
无法更改定义对象标识的成员。
请改为考虑添加具有新标识的新对象,并删除现有的对象。”
改主键TM的值改不了,但把p.TM = tmName.Text;删除后,只更新条码的价格p.TMJG 能更新成功。
请问如何用linq的方法更改主键TM的值?谢谢!

解决方案 »

  1.   

    db.SubmitChanges(); 这句话,不能放到循环中,这是对实体对象模型变化 后的一次向数据库的提交一般来说只能在你在内存上的工作完成以后再来统一的一次提交。
      

  2.   

    我在后台用sql语句:update SPDA set TM = 新值 where TM=原值
    确能改主键的值。
      

  3.   

    不好意识,我的程序贴错了,db.SubmitChanges();是在循环的外边,但错误提示依旧。
    源程序为:
    foreach(SPDA p in pmatches) 
    {            
      p.TM = tmName.Text; 
      p.TMJG = decimal.Parse(tbPrice.Text.Trim()); 
    }
     db.SubmitChanges(); 
     
      

  4.   

    Linq2sql和entity framework不允许修改主键值。
    办法是,新建一个项,将除主键外的字段复制过去,删除原记录,提交新纪录
      

  5.   

    不会吧!linq怎么蠢啊,还要先删除,后再插入记录。
      

  6.   

    这不是蠢,这是保证数据有效性。
    linq2sql/entity采用乐观并发处理数据,即update更新字段 where 所有未更新字段。这种方式,保证update的是你处理的这一条记录。当你修改的过程中,有人改了数据,那么你的update将失败,采用这种方式防止并发导致的数据覆盖。然后,你如果要更新主键,那么,根据该机制,他将主键外的字段作为where条件,但非主键的字段是可能重复的,可能会更新数条记录,即便让你更新,主键的唯一性也会导致更新失败。出于以上的机制,linq2sql/entity不允许更新主键。更多说明,google“数据库并发”
      

  7.   

    呵呵,请确认你知道“主键”的含义请确认在sql你能修改“主键”“主键”作为数据识别标识是不可修改的,比方说我们的身份证号是唯一的,如果说你把身份证号给改了,你认为你以后的养老保险给发给谁。
      

  8.   

    我有一个商品档案表SPDA,主键为条码TM,当TM输入错误时,过后可以修改。
    对于把可修改的列作为主键的问题有待考虑...
      

  9.   

    void BeforeInsert(DataType data,IQueryable <DataType> source) 

        if(source.Any(x=>x.Key==data.Key)) 
            throw new Exception("键值Key重复!"); 
    } 或者: void BeforeInsert(DataType data) 

        data.Key=Guid.NewGuid().ToString("N"); 

      

  10.   

    TM 是主键,linq不允许修改主键
    删除在添加