我一直在寻找一个通用的解决方案,用于在linq中从c#级联删除到sql,但我还找不到。
因此,我提出了自己的解决方案,处理一对多关系。
这不是删除实体的一般方法,但某些边缘情况需要它。所以在它进入生产环境之前,我想知道你对它有什么看法?
它似乎奏效了,但利弊是什么,哪里会失败?请注意,它只应该遍历关系树的下方。
public class CascadingDeleteHelper
{
public void Delete(object entity, Func<object, bool> beforeDeleteCallback)
{
if (!(entity is BusinessEntity))
{
throw new ArgumentException("Argument is not a valid BusinessEntity");
}
if (beforeDeleteCallback == null || beforeDeleteCallback(entity))
{
Type currentType = entity.GetType();
foreach (var property in currentType.GetProperties())
{
var attribute = property
.GetCustomAttributes(true)
.Where(a => a is AssociationAttribute)
.FirstOrDefault();
if (attribute != null)
{
AssociationAttribute assoc = attribute as AssociationAttribute;
if (!assoc.IsForeignKey)
{
var propertyValue = property.GetValue(entity, null);
if (propertyValue != null && propertyValue is IEnumerable)
{
IEnumerable relations = propertyValue as IEnumerable;
List<object> relatedEntities = new List<object>();
foreach (var relation in relations)
{
relatedEntities.Add(relation);
}
relatedEntities.ForEach(e => Delete(e, beforeDeleteCallback));
}
}
}
}
SingletonDataContext.DataContext.GetTable(currentType).DeleteOnSubmit(entity);
SingletonDataContext.DataContext.SubmitChanges();
}
}
}
非常感谢
negra
解决方案的优点:
- 它是通用的
- 它不需要在架构更新时更改数据库
缺点:
- 易出错(更多自定义代码)
- 性能(很可能)不是最佳的
有一个不那么复杂但维护工作量更大的解决方案,就是将ON CASCADE DELETE
规则添加到数据库中。