【问题标题】:Updating related entities in an ASP.NET MVC application using Entity Framework使用实体框架更新 ASP.NET MVC 应用程序中的相关实体
【发布时间】:2015-01-04 01:32:23
【问题描述】:

假设我有两个类,一个 Company 类和一个 Customer 类。

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;}
}

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

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

当表单被发送回服务器时,我有用户选择的带有新客户 ID 的公司模型。现在我想使用 Entity Framework 更新数据库。

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

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

一旦我在我的存储库上调用更新,我就会得到一个异常,上面写着“属性 'Id' 是对象的关键信息的一部分,不能被修改”。我的存储库上的更新方法如下所示:

    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 从数据库中检索客户实体并将 Company.Customer 分配给检索到的客户,但这实际上是一个非常简化的示例。实际上,我拥有的相关实体远不止一个,如果我必须访问数据库以查找每个相关实体以进行更新,我会发现性能很快就会成为问题。

【问题讨论】:

    标签: asp.net asp.net-mvc entity-framework


    【解决方案1】:

    您希望对实体执行的操作是访问外键。但是,您不能通过相关实体直接访问外键,而是访问该相关实体的主键。

    即而不是在 SQL 中访问 Company Customer_Id 属性,而是访问 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 实体。

    【讨论】:

    • 嗯嗯。我现在觉得很傻。现在您已经解释过了,这似乎很明显。谢谢你。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    • 1970-01-01
    • 2014-09-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多