简体   繁体   English

级联删除-映射到表的复杂类型

[英]Cascade on delete - Complex type mapped to a table

Please consider the following relationship: 请考虑以下关系:

Car (entity) 1 ----------------------> * Wheels (Entity) 汽车(实体)1 ----------------------> *车轮(实体)

Wheel (entity) 1 --------->1 Nut (Complex type) 车轮(实体)1 ---------> 1螺母(复杂类型)

Wheel (entity) 1 --------->1 Rim (complex type) 车轮(实体)1 ---------> 1轮辋(复杂类型)

Both Nut and Rim complex types are mapped to tables named Nuts and Rims. Nut和Rim复杂类型都映射到名为Nuts和Rims的表。 I am using Wheel ID as Nuts and Rims primary key. 我正在使用Wheel ID作为螺母和轮辋的主键。

Now, when attempting to delete Car using code, I get the following exception: 现在,当尝试使用代码删除Car时,出现以下异常:

System.InvalidOperationException: The operation failed: The relationship could not be changed   because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.
at System.Data.Entity.Core.Objects.ObjectContext.PrepareToSaveChanges(SaveOptions options)
at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions options, Boolean  executeInExistingTransaction)
at System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions options)
at System.Data.Entity.Internal.InternalContext.SaveChanges()
at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
at System.Data.Entity.DbContext.SaveChanges()

When attempting to do this in MS- SSMS, I get this error: The DELETE statement conflicted with the REFERENCE constraint "FK_dbo.Nuts_dbo.Wheel_Id". 尝试在MS-SSMS中执行此操作时,出现以下错误:DELETE语句与REFERENCE约束“ FK_dbo.Nuts_dbo.Wheel_Id”冲突。 The conflict occurred in database "DatabaseName", table "dbo.Nuts", column 'Id'. 数据库“ DatabaseName”的表“ dbo.Nuts”的列“ Id”中发生了冲突。

Given, that complex types are required parameters for an entity and have a one-to-one relationship, why wouldn't cascade delete be ON by default in this scenario? 鉴于复杂类型是实体的必需参数并具有一对一关系,因此在这种情况下默认情况下为什么不将层叠删除默认设置为ON? Second, how should go about deleting CAR and its related many Wheels along with all associated Nuts and Rims. 其次,应该如何删除CAR及其相关的多个Wheels以及所有相关的Nuts和Rims。 Lastly, in my case, a car has thousands of wheels. 最后,以我为例,汽车有数千个车轮。 Is it a good idea to this in code or to use stored procedures? 在代码中还是使用存储过程是个好主意?

Thanks. 谢谢。

As Ben Robinson mentions in his comment, the purpose of classes attributed with [ComplexType] is to have their properties mapped to columns within the table of the containing type. 正如本·罗宾逊(Ben Robinson)在评论中提到的那样,使用[ComplexType]赋予类的目的是将其属性映射到包含类型的表中的列。 There should be no Nut or Rim tables. 不应有“坚果”或“轮辋”表。 If this isn't the desired behaviour then they shouldn't be complex types. 如果这不是期望的行为,则它们不应为复杂类型。

Let's assume they shouldn't be complex types and work out why they are not cascade deleting. 让我们假设它们不应该是复杂的类型,并弄清楚为什么它们不是级联删除的原因。 Concentrating on Nut, and assuming you are not using fluent configuration, I suspect you would need to have a navigation property to Wheel on the Nut, as well as the WheelId. 专注于螺母,并假设您未使用流利的配置,我怀疑您将需要具有“螺母上的滚轮”以及WheelId的导航属性。 The WheelId would be marked with [Key] and [ForeignKey(Wheel)], I think. 我认为WheelId将标有[Key]和[ForeignKey(Wheel)]。 The main point is the navigation property. 要点是导航属性。

With fluent configuration you would have the navigation property to Wheel and then, in the configuration for Wheel, you would have: 使用流利的配置,您将导航属性设置为Wheel,然后在Wheel的配置中,您将具有:

HasRequired(wheel => wheel.Nut)
  .WithRequiredDependent(nut => nut.Wheel);

Another point to note is that the cascade delete, if it isn't generated to your taste, can be modified inside a migration in the foreign key creation via a method argument. 要注意的另一点是,如果不是按照您的喜好生成的,则可以通过方法参数在外键创建的迁移过程中修改级联删除。

Finally, to answer your question about batch delete: Cascade delete will be done in the database if you delete the Car and it cascade deletes the Wheel, and that should be fast. 最后,回答有关批量删除的问题:如果您删除Car并级联删除Wheel,则级联删除将在数据库中完成,这应该很快。 If you want to perform deletes of many wheels for a car separately then have a look at Entity Framework Extensions: http://efe.codeplex.com/ 如果要分别删除汽车的多个车轮,请查看Entity Framework Extensions: http : //efe.codeplex.com/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM