我使用Entity Framework Code First + Durandal + Breeze开展项目。
我有这些实体模型:
public class Packing
{
[Key]
public int Id { get; set; }
public string PackingDescription { get; set; }
...
public virtual List<Isotope> Isotopes { get; set; }
public virtual List<PhysicalForm> PhysicalForms { get; set; }
public virtual List<ChemicalForm> ChemicalForms { get; set; }
}
public class Isotope
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
...
public int PackingId { get; set; }
public virtual Packing Packing { get; set; }
}
public class ChemicalForm
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
...
public int PackingId { get; set; }
public virtual Packing Packing { get; set; }
}
public class PhysicalForm
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
...
public int PackingId { get; set; }
public virtual Packing Packing { get; set; }
}
当我运行我的项目时,我的实体框架代码优先数据库已经创建。
首先,我直接在我的数据库中测试级联删除'手动'。当我有一个包含多个同位素的包装并删除包装时,所有级联的同位素都将被删除。这对我来说没问题。
现在在我的项目运行时使用breeze,当我尝试相同的场景时:删除这样的Packing
元素:
var deletePackings = function (packingsObservable) {
// Input: packingsObservable: an observable filled with a list of packings to delete
// Output: none
for (var i = 0; i < packingsObservable().length; i++) {
packingsObservable()[i].entityAspect.setDeleted();
};
return manager.saveChanges();
};
我收到了以下错误:
UPDATE语句与FOREIGN KEY约束“FK_dbo.Isotopes_dbo.Packings_PackingId”冲突。冲突发生在数据库\“TRANSPORTBOEKDB \”,表\“dbo.Packings \”,列'Id'。\ r \ n语句已终止。“}
现在我读了另一个SO post那个
Breeze尚不支持客户端“级联”删除(我们正在考虑这个),您需要迭代已加载的任何客户端订单并“分离”它们。
这就是我在申请中收到错误的原因吗?
我是否必须遍历已加载的任何子实体并“分离”它们?
更新
通过代码用微风手动分离任何子实体可以解决问题,但这很痛苦:
var deletePackings = function (packingsObservable) {
// Input: packingsObservable: an observable filled with a list of packings to delete
// Output: none
// Remark: we loop from end to begin of the observable!
var entity;
// Since Breeze does not yet support client side 'cascaded' deletes (we are considering this one),
// you will need to iterate over any child entity that are already loaded and 'detach' them.
for (var i = packingsObservable().length - 1; i >= 0; i--) {
// Detach any child entities of type isotope
for (var j = packingsObservable()[i].isotopes().length - 1; j >= 0; j--) {
entity = packingsObservable()[i].isotopes()[j];
manager.detachEntity(entity);
}
// Detach any child entities of type chemicalForm
for (var j = packingsObservable()[i].chemicalForms().length - 1; j >= 0; j--) {
entity = packingsObservable()[i].chemicalForms()[j];
manager.detachEntity(entity);
}
// Detach any child entities of type physicalForm
for (var j = packingsObservable()[i].physicalForms().length - 1; j >= 0; j--) {
entity = packingsObservable()[i].physicalForms()[j];
manager.detachEntity(entity);
}
packingsObservable()[i].entityAspect.setDeleted();
};
return manager.saveChanges();
};
没有更好的解决方案?
答案 0 :(得分:2)
如果需要,在SQL中进行级联删除,忘记在客户端,只需刷新数据。
或者你可以为agreggate实体添加新的IsActive列,这是我最喜欢的方法,我害怕DB删除:)
答案 1 :(得分:1)
支持级联删除是一个非常合理的请求。
请在此处添加对客户端级联删除支持的投票:Breeze User Voice。我们非常重视这个场所,以确定添加到Breeze产品的功能。
答案 2 :(得分:1)
微风作者正在考虑的功能是客户端级联删除,但微风也不支持服务器端级联删除。您必须执行某些操作才能使用服务器端级联删除。
setDeleted使所有引用缓存中的fkey值都为空 - 即使fkey不可为空。如果引用记录具有不可为空的fkey约束,则需要阻止保存子记录,因为UPDATE将失败。在保存完成此目标之前,您可以从缓存中驱逐子级,并允许您在没有参数的情况下调用saveChanges()。或者,您可以传递包含已设置已删除记录的数组。那么你可能想要在保存后驱逐孩子们。或者您可以停止使用该实体管理器。