猿问

使用实体框架更新主键值

我正在尝试从实体框架中更新复合主键的一个值,并且收到此错误:“属性'CustomerID'是对象键信息的一部分,无法修改。”


这是我的代码:


Dim customer As Customer = (From c In db.Customer Where c.CustomerID = "xxx" AndAlso c.SiteKey = siteKey).FirstOrDefault

customer.CustomerID = "fasdfasdf"

db.SaveChanges()

似乎太简单了。您无法在实体框架内更新主键,这是真的吗?我找不到有关该主题的任何文档。谢谢!


森林海
浏览 653回答 3
3回答

人到中年有点甜

您不能并且有充分的理由。请参阅KM评论。我说您可以做的一件事是有两个表,其中一个表包含匿名数据,另一个表在真实用户登录后存储真实用户数据。或者您可以(未经测试或由我完成)具有这种表布局:---Customers----AutoNumber PK <- This links to all other tables in your database, and does NOT change.CustomerID&nbsp; <- This can change.CustomerType <- Anonymous or logged in.&nbsp;&nbsp;当他们登录时,将CustomerType和CustomerID更改为所需的名称。因此,您的查询可能如下所示:Dim customer As Customer = (From c In db.Customer _&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Where c.CustomerID = {Some temp ID} _&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AndAlso c. CustomerType = "Anonymous").FirstOrDefault// After user logs in.customer.CustomerID = {Make a new user ID here}customer.CustomerType = "LoggedIn" {or what ever}db.SaveChanges()请注意,自动编号主键永远不会更改。这样一来,您与客户表有关系的任何表仍然可以使用,而不必对主键进行级联更新(这就像用铅笔刺中眼睛一样)。

阿晨1998

如果在任何时候都可能只有一个数据库上下文实例,那么修改pk不会是一个问题。但是每个上下文实例都维护自己的缓存,并且可以缓存要修改的记录。EF与数据库的交互使用pk(来自上下文缓存)来标识它们正在查询的记录。如果上下文对象可以更新持久性密钥,则其他上下文对象用来标识该记录的信息将立即且永久错误。简而言之,如果更新主键,则可能在上下文的所有其他实例中使缓存无效,这将从根本上破坏EF。这是更新pk不好的主要原因之一。
随时随地看视频慕课网APP
我要回答