2011-05-09 82 views
3

我有tbl_names与以下字段:如何用linq更新一个关键字段到SQL?

Id int 
Name nvarchar(10) 
family nvarchar(20) 


Id Name Family 
1  John  Smith 

和假设Idname和是主键合(化合物主键)。 ,我想根据Id字段的值更新name字段。

DataclassesContext dac=new DataClassesContext(); 
var query=from record in Dac.tbl_name where record.id=1 select record; 
query.name="Raymond"; 
Dac.Submitchanges(); 

,但我碰到下面的错误:

Value of member 'co_Workshop' of an object of type 'Tbl_Workshop' changed. 
A member defining the identity of the object cannot be changed. 
Consider adding a new object with new identity and deleting the existing one instead. 

是不是因为name字段是主键?为什么我不能使用linq更新主键字段?

+2

我想不出有一次我更新了主键。不是说你没有理由...我从来没有。有趣的是,它不会让你。这可能是因为它是唯一可以链接到数据库的标识符?所以你必须用更新的密钥复制它,添加它,然后删除旧密钥。 – Mikecito 2011-05-09 03:53:46

+1

为什么你会有'{id,name}'的联合身份?为什么不保持'id'独特? – 2011-05-09 03:54:49

+0

我正在处理旧数据库,无法更改其结构。是的,你是对的没有理由,但我需要它 – 2011-05-09 03:57:39

回答

4

我不知道,你应该找到解决的办法。我无法想象为什么改变一个PK值是一个好主意。 PK的整个性质是它是行的稳定标识符。

对于你的情况,你应该删除并重新创建PK只是“Id”字段,然后如果你需要提高性能查询过滤“名称”​​,那么只需在“名称”字段添加一个索引。您只使用“Id”字段查找记录的事实支持这一想法。

编辑: 我回答之前,有问题的意见。现在我看到OP的评论“这是一个旧的数据库,不能改变它的结构”,我会说如果没有FK指向这个PK,那么这应该是一个相当直接的变化(如上所述,使用“Id”字段删除并重新创建PK)。如果有 FKS指向它,然后一个选项(虽然不是一个很好的选择,它可能无法在所有的RDBMS的工作)是:

  1. 降FKS
  2. 降PK
  3. 创建在刚刚“ID”字段
  4. 新PK的“ID”和“名称”
  5. 创建唯一索引重新创建FK的指向唯一索引

这将在Microsoft SQL Server上工作,尽管我不喜欢FK指向UNIQUE INDEX的想法,但它应该允许您现在具有相同的结构加上 LINQ只会看到单个字段PK在“ ID“并允许更新。

1

如有可能,解决方法是删除主键值需要更新的记录,并在其位置创建新记录。

0

有同样的问题。由于遗留原因,我无法删除我需要更新的列作为主键的一部分。

一个简单的解决方案是在这种情况下不使用Linq,但使用T_SQL并做一个简单的更新。

update tbl_name set name = 'Raymond' where id = 1