[英]How do I create a table that has a composite key each member of which is a foreign key member to other tables
I am trying to do code first with annotations (for the first time) on an MVC project. 我试图在MVC项目上首先使用注释(第一次)来编写代码。
I have created the following POCOs. 我创建了以下POCO。
[Table("Customers")]
public partial class Customer
{
public int Id { get; set; }
[Required]
[DisplayName("First Name")]
public string FirstName { get; set; }
[DisplayName("Last Name")]
[Required]
public string LastName { get; set; }
//other properties...
}
[Table("Vehicles")]
public partial class Vehicle
{
[Required]
public int Id { get; set; }
[Required]
public int CustomerId { get; set; }
[Required]
public string Make { get; set; }
[Required]
public string Model { get; set; }
[Required]
public string Year { get; set; }
//other fields
[ForeignKey("CustomerId")]
public virtual Customer Customer { get; set; }
}
[Table("CustomerAppointments")]
public partial class CustomerAppointment
{
[Key,Column(Order=0)]
public int CustomerId { get; set; }
[Key,Column(Order=1)]
public int VehicleId { get; set; }
public DateTime? AppointmentDate { get; set; }
public DateTime? AppointmentTime { get; set; }
public string AvailableDays { get; set; }
//other fields
[ForeignKey("CustomerId")]
public virtual Customer Customer { get; set; }
[ForeignKey("VehicleId")]
public virtual Vehicle Vehicle { get; set; }
}
I think my intent here is fairly obvious. 我认为我的意图非常明显。 I have customers. 我有客户。 Those customers have vehicles. 那些客户有车辆。 I want to create a table CustomerAppointments where a customer and one of the customers vehicles is scheduled for a service. 我想创建一个CustomerAppointments表,其中客户和一个客户车辆被安排用于服务。
For the record, this is not the whole model and has been simplified for the purposes of the question. 为了记录,这不是整个模型,并且为了问题的目的已经简化。
I am using MvcScaffolding to build out the EF items and the views. 我正在使用MvcScaffolding来构建EF项目和视图。
Everything compiles but when I try to navigate to the Customers page (actually a class not mentioned that references customers) I am getting the following error... 一切都编译但当我尝试导航到客户页面(实际上是一个未提及引用客户的类)时,我收到以下错误...
Introducing FOREIGN KEY constraint 'FK_dbo.CustomerAppointments_dbo.Vehicles_VehicleId' on table 'CustomerAppointments' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
I have tried different annotations and even tried to use the fluent API with something like this... 我尝试过不同的注释,甚至尝试使用这样的流程API ......
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<CustomerAppointment>()
.HasRequired(ca => ca.Customer)
.WithRequiredPrincipal()
.WillCascadeOnDelete(false);
modelBuilder.Entity<CustomerAppointment>()
.HasRequired(ca => ca.Vehicle)
.WithRequiredPrincipal()
.WillCascadeOnDelete(false);
}
But I cannot get it to work. 但我无法让它发挥作用。 I have read every sample I can find on google and SO but to no avail. 我已经阅读了我可以在Google和SO上找到的每个样本,但无济于事。
PS...if this can work with Annotations only that would be my preference. PS ...如果这可以使用注释只是我的偏好。
Your model has two cascading delete paths from Customer
to CustomerAppointment
when a Customer
is deleted: 你的模型有两个级联删除从路径Customer
到CustomerAppointment
当Customer
被删除:
Customer
-> Vehicle
-> CustomerAppointment
Customer
- > Vehicle
- > CustomerAppointment
Customer
-> CustomerAppointment
Customer
- > CustomerAppointment
That's not allowed in SQL Server and causes the exception. 这在SQL Server中是不允许的并导致异常。 You need to disable cascading delete for at least one of those three subpaths which is only possible with Fluent API. 您需要为这三个子路径中的至少一个禁用级联删除,这只能通过Fluent API实现。 For example the Customer
-> Vehicle
path: 例如Customer
- > Vehicle
路径:
modelBuilder.Entity<Vehicle>()
.HasRequired(v => v.Customer)
.WithMany()
.HasForeignKey(v => v.CustomerId)
.WillCascadeOnDelete(false);
You could also make CustomerId
nullable to have an optional relationship in which case EF will disable cascading delete by default. 您还可以使CustomerId
空而具有可选关系,在这种情况下,EF将默认禁用级联删除。 But changing a required to an optional relationship expresses a change in business rules which I wouldn't do just to avoid Fluent API. 但是将所需关系更改为可选关系表示业务规则的更改,我不会仅仅为了避免使用Fluent API。
BTW: Is it really correct that CustomerAppointment
should have a composite primary key? 顺便说一句: CustomerAppointment
应该有一个复合主键是否真的正确? It would mean that a given customer with a given vehicle could only have one service appointment. 这意味着具有给定车辆的给定客户只能有一个服务预约。 Couldn't there be many appointments for the same customer/vehicle combination at different appointment dates? 在不同的预约日期,相同的客户/车辆组合是否有很多预约? If yes, you should rather have a separate key for CustomerAppointment
and CustomerId
and VehicleId
would be just foreign keys without being part of the primary key. 如果是,您应该为CustomerAppointment
和CustomerId
分别使用单独的密钥,而VehicleId
只是外键而不是主键的一部分。
By convention, cascade deletes are handled by the introduction of the actual foreign key into your model. 按照惯例,通过将实际外键引入模型来处理级联删除。 If you use a non-nullable foreign key, it will require delete. 如果使用不可为空的外键,则需要删除。 Use a nullable foreign key to turn it off. 使用可以为空的外键将其关闭。
Change your class to the following by making the foreign keys nullable: 通过使外键可为空来将您的类更改为以下内容:
[Table("CustomerAppointments")]
public partial class CustomerAppointment
{
[Key,Column(Order=0)]
public int? CustomerId { get; set; }
[Key,Column(Order=1)]
public int? VehicleId { get; set; }
public DateTime? AppointmentDate { get; set; }
public DateTime? AppointmentTime { get; set; }
public string AvailableDays { get; set; }
//other fields
[ForeignKey("CustomerId")]
public virtual Customer Customer { get; set; }
[ForeignKey("VehicleId")]
public virtual Vehicle Vehicle { get; set; }
}
Remember to also remove the fluent mapping. 请记住也删除流畅的映射。
From http://msdn.microsoft.com/en-US/data/jj679962 来自http://msdn.microsoft.com/en-US/data/jj679962
If a foreign key on the dependent entity is not nullable, then Code First sets cascade delete on the relationship. 如果依赖实体上的外键不可为空,则Code First会在关系上设置级联删除。 If a foreign key on the dependent entity is nullable, Code First does not set cascade delete on the relationship, and when the principal is deleted the foreign key will be set to null. 如果依赖实体上的外键可以为空,则Code First不会在关系上设置级联删除,并且当删除主体时,外键将设置为null。
您最好使用数据库优先方法,然后使用ado enity数据模型生成模型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.