EF 6.0 - 更新与 EntityState.Modified 的关系

Posted

技术标签:

【中文标题】EF 6.0 - 更新与 EntityState.Modified 的关系【英文标题】:EF 6.0 - Updating Relationship with EntityState.Modified 【发布时间】:2019-11-19 06:47:47 【问题描述】:

在具有以下(简化)模型的 ASP.NET MVC5 应用程序中:

public class Customer

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid CustomerID  get; set; 
    public string Name  get; set; 
    public string PrimaryContact  get; set; 
    public string Email  get; set; 
    public string PhoneNumber  get; set; 
    public Reseller Reseller  get; set;   

public class Reseller

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid CompanyId  get; set; 

    public ICollection<Customer> Customers  get; set; 

我希望能够更新与客户关联的经销商。当尝试通过将客户实体标记为已修改 (ctx.Entry(customer).State = EntityState.Modified) 来更新客户实体时,除了经销商的 CompanyID 之外的所有列都会更新。据我了解,Modified 将所有字段标记为脏并更新所有字段,但这里不会发生这种情况。

以下是用于更新客户的控制器操作。我已检查并在传入模型中正确设置了经销商的正确 CompanyID:

[HttpPost]
public ActionResult Edit(Customer customer)

    if (ModelState.IsValid)
    
        using (var ctx = new DbContext())
        
            ctx.Entry(customer).State = EntityState.Modified;
            ctx.SaveChanges();

            return RedirectToAction("Info", new  id = customer.CustomerID );
        
    

    return View(customer);

调用 SaveChanges 时,会生成以下 SQL。请注意,Reseller CompanyID 不包含在查询中:

UPDATE [dbo].[Customer]
SET [Name] = @0, [PrimaryContact] = @1, [Email] = @2, [PhoneNumber] = @3
WHERE ([CustomerID] = @4)

-- @0: 'Sample Customer iuhiuhi' (Type = String, Size = -1)

-- @1: 'Joe Bloggs' (Type = String, Size = -1)

-- @2: 'example@example.com' (Type = String, Size = -1)

-- @3: '123456789' (Type = String, Size = -1)

-- @4: 'e4b9e8d3-9f92-e811-baa4-3052cb3d0eb2' (Type = Guid)

即使它是客户实体的一部分。

【问题讨论】:

CompanyID 是主键,所以你不能更新它。 我不想更改CompanyID - 我想更新客户以拥有不同的CompanyID 将状态设置为已修改仅影响标量属性,而不影响导航属性。 【参考方案1】:

将 ResellerId 添加到客户模型

public class Customer

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid CustomerID  get; set; 
    public string Name  get; set; 
    public string PrimaryContact  get; set; 
    public string Email  get; set; 
    public string PhoneNumber  get; set; 
    public Guid ResellerId  get; set; 
    [ForeignKey("ResellerId")]
    public Reseller Reseller  get; set;   

然后更改 ResellerId

【讨论】:

以上是关于EF 6.0 - 更新与 EntityState.Modified 的关系的主要内容,如果未能解决你的问题,请参考以下文章

EF--EntityState相互转换

EF中的EntityState状态解读

无法更新EF6中的实体?

EF部分字段更新,忽略为null字段

EF Core性能优化

GroupBy 与 EF Core 6.0 和 SQL Server