为了账号安全,请及时绑定邮箱和手机立即绑定

使用实体框架更新主键值

使用实体框架更新主键值

森林海 2019-12-04 15:29:41
我正在尝试从实体框架中更新复合主键的一个值,并且收到此错误:“属性'CustomerID'是对象键信息的一部分,无法修改。”这是我的代码:Dim customer As Customer = (From c In db.Customer Where c.CustomerID = "xxx" AndAlso c.SiteKey = siteKey).FirstOrDefaultcustomer.CustomerID = "fasdfasdf"db.SaveChanges()似乎太简单了。您无法在实体框架内更新主键,这是真的吗?我找不到有关该主题的任何文档。谢谢!
查看完整描述

3 回答

?
人到中年有点甜

TA贡献1895条经验 获得超7个赞

您不能并且有充分的理由。请参阅KM评论。


我说您可以做的一件事是有两个表,其中一个表包含匿名数据,另一个表在真实用户登录后存储真实用户数据。


或者您可以(未经测试或由我完成)具有这种表布局:


---Customers----

AutoNumber PK <- This links to all other tables in your database, and does NOT change.

CustomerID  <- This can change.

CustomerType <- Anonymous or logged in.  

当他们登录时,将CustomerType和CustomerID更改为所需的名称。


因此,您的查询可能如下所示:


Dim customer As Customer = (From c In db.Customer _

                            Where c.CustomerID = {Some temp ID} _

                            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()

请注意,自动编号主键永远不会更改。这样一来,您与客户表有关系的任何表仍然可以使用,而不必对主键进行级联更新(这就像用铅笔刺中眼睛一样)。


查看完整回答
反对 回复 2019-12-04
?
阿晨1998

TA贡献2037条经验 获得超6个赞

如果在任何时候都可能只有一个数据库上下文实例,那么修改pk不会是一个问题。但是每个上下文实例都维护自己的缓存,并且可以缓存要修改的记录。

EF与数据库的交互使用pk(来自上下文缓存)来标识它们正在查询的记录。如果上下文对象可以更新持久性密钥,则其他上下文对象用来标识该记录的信息将立即且永久错误。

简而言之,如果更新主键,则可能在上下文的所有其他实例中使缓存无效,这将从根本上破坏EF。这是更新pk不好的主要原因之一。


查看完整回答
反对 回复 2019-12-04
  • 3 回答
  • 0 关注
  • 646 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信