使用 Entity Framework 更新 ASP.NET MVC 应用程序中的相关实体

Updating related entities in an ASP.NET MVC application using Entity Framework

假设我有两个 class,一个公司 class 和一个客户 class。

public class Company
{
    public int Id {get; set;}
    public Customer Customer {get; set;}
}

public class Customer
{
    public int Id {get; set;}
    public string Name {get; set;}
}

我希望能够使用下拉列表更新与公司关联的客户。因此,我的控制器中的编辑方法创建了一个视图模型。

public class ViewModel
{
    public List<Customer> AvailableCustomers {get; set;}

    public Company Company {get; set;}
}

该视图创建了一个带有下拉列表的表单,select 客户(使用 Knockout)可以从该列表中选择。

<select data-bind="attr: {name: 'Company.Customer.Id'}, options: AvailableCustomers(), optionsText: 'Name', optionsValue: 'Id', value: Company.Customer.Id"></select>

当表单回发到服务器时,我得到了带有用户新客户 ID select 的公司模型。现在我想使用 Entity Framework.

更新数据库

我使用在表单数据中发回的公司 ID 从数据库中更新公司,这只是我之前的视图模型。现在我想用新客户更新公司。此时我所掌握的唯一信息是用户从下拉列表中 select 编辑的公司 ID。所以我做了这样的事情:

var companyBeingUpdated = repository.GetByKey<Company>(Company.Id);
companyBeingUpdated.Customer.Id = Company.Customer.Id;

我在我的存储库上调用更新后,立即收到一个异常 "The property 'Id' is part of the object's key information and cannot be modified"。我存储库上的更新方法如下所示:

    public void Update<TEntity>(TEntity entity) where TEntity : class
    {
        var entry = this._dbContext.Entry(entity);

        if (entry.State == EntityState.Detached)
        {
            this._dbContext.Set<TEntity>().Attach(entity);
        }

        entry.State = EntityState.Modified;
    }

我显然在 Entity Framework 上做错了什么。我可以使用 SQL 语句轻松执行此操作,但我想了解我在使用 EF 时做错了什么。

当我仅有的信息是表单数据中回发的客户 ID 时,如何使用 EF 更新公司对象的客户相关实体?

我知道我可能可以使用 Id 从数据库中检索 Customer 实体并将 Company.Customer 分配给检索到的 Customer,但这实际上是一个非常简化的示例。实际上,我拥有的不仅仅是一个相关实体,如果我必须前往数据库查找每个相关实体以进行更新,我会发现性能很快就会成为一个问题。

你想对你的实体做的是访问外键。但是,您不能通过相关实体直接访问外键,而是访问该相关实体的主键。

即您访问的不是 Company Customer_Id 属性 SQL,而是 Customer Id 属性.

您可以在 Entity Framework 中将外键暴露给您的模型,从而允许您进行您想要的更新类型。

public class Company
{
    public int Id {get; set;}

    [ForeignKey("CustomerId")]
    public Customer Customer {get; set;}
    public int CustomerId {get;set;}
}

现在,您可以像 companyBeingUpdated.CustomerId = Company.CustomerId; 一样进行更新,而不必进行查找来检索完整的 Customer 实体。