假设你有下面所示的具有级联删除关系的数据库表结构:
这里的级联删除规则是,当删除Category的时候,应当级联删除与之相关联的Products。
如果你根据上面的数据表结构生成相应的EF模型,像下面这样,看上去没有什么异常,这里并没有显示与级联删除相关的信息:
但是如果你看一下后台的CSDL文件,你就会发现有一点不同的地方,如下面文件所示:
<Association Name="FK_Products_Categories">
<End Role="Categories" Type="TipsModel.Store.Categories" Multiplicity="1">
<OnDelete Action="Cascade" />
</End>
<End Role="Products" Type="TipsModel.Store.Products" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="Categories">
<PropertyRef Name="ID" />
</Principal>
<Dependent Role="Products">
<PropertyRef Name="CategoryID" />
</Dependent>
</ReferentialConstraint>
</Association>
关注一下节点<OnDelete>,这里指明了这个级联删除的关系,当Category被删除的时候,相关联的Products“或许”会也被删除。
我在这里故意使用了“或许”这个词,而没有用”应该”是因为EF在这里的删除并不会作用于数据库。
EF在这里只负责ObjectContxt在执行了SaveChanges()方法之后的正确性,换句话说,EF在这里只是试图在数据库发生了级联删除动作以后,去同步相对应的ObjectContext。
如果你使用SQlProfiler来查看,你就会注意到,当EF发起Delete对父对象发起Delete请求的时候,它也会同时会对已经加载入ObjectContext中的依赖子对象向数据库发起Delete请求。
这里所发生的事情的本质是EF期望在数据库中删除父对象的时候,删除所有数据库中与其相关的子对象,所以他向自己发起了一个额外的Delete请求以删除所有已经加载入ObjectContext中的依赖对象。
上面的表述有一些拗口,但总结起来就是EF只会删除已经加载入内存的依赖对象,而不会对未存在于内存中的以来对象进行任何操作。
下面是两条黄金法则:
在我们努力保持ObjectContext和database之间的数据同步的时候,我们针对多级级联删除的尝试可能会失败,比如你有如下的对象关系:
Category –> Product –> Order
有可能会出现这样的情况,假设在ObjectContext有一个具有关联性的Category和Order,但其中间对象Product对象并没有被加载进ObjectContext,这个时候如果你实施了规则1,在ObjectContext和Database中都添加了级联删除规则,当你删除Category对象的时候,在数据库中,按照规则,相关的Product和Order都会被删除,但是在ObjectContext中,由于Product对象没有被加载,级联删除规则将会被阻断,Order对象将仍然存在,状态仍将是unchanged,尽管Category已经被删除,这将使ObjectContext和database产生不同步的情况。
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。