使用 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
实体。
假设我有两个 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
实体。