我们说我有两个班级,一个公司班级和一个客户班级。
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;}
}
我希望能够使用下拉列表更新与公司关联的客户。因此,我的控制器中的编辑方法会创建一个viewmodel。
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来更新公司数据库,这只是我之前的viewmodel。现在我想用新客户更新公司。此时我唯一的信息是用户从下拉列表中选择的公司ID。所以我做了这样的事情:
var companyBeingUpdated = repository.GetByKey<Company>(Company.Id);
companyBeingUpdated.Customer.Id = Company.Customer.Id;
一旦我在我的存储库上调用更新,我就会得到一个例外情况,即&#34;属性&#39; Id&#39;是对象的关键信息的一部分,不能修改&#34;。我的存储库上的更新方法如下所示:
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,但这实际上是一个非常简单的示例。实际上,我不仅仅是一个相关的实体,如果我必须访问数据库以查找每个相关实体以进行更新,我可以看到性能很快就会成为一个问题。
答案 0 :(得分: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
实体。