C# NHibernate:呼叫。删除集合上的所有内容
在通过NHibernate检索集合时,我遇到无法使用C# NHibernate:呼叫。删除集合上的所有内容,c#,nhibernate,fluent-nhibernate,C#,Nhibernate,Fluent Nhibernate,在通过NHibernate检索集合时,我遇到无法使用.RemoveAll的问题 我有一个名为Order的实体,我通过NHibernate保存它 订单有许多订单项。以下是我对此关系的映射: mapping.HasMany(o => o.Items) .Cascade.AllDeleteOrphan() .AsList() .Inverse(); 在我的域中,如下所示: publ
.RemoveAll
的问题
我有一个名为Order
的实体,我通过NHibernate保存它
订单
有许多订单项
。以下是我对此关系的映射:
mapping.HasMany(o => o.Items)
.Cascade.AllDeleteOrphan()
.AsList()
.Inverse();
在我的域中,如下所示:
public virtual IList<OrderItem> Items { get; set; }
public virtual void RemoveItem(string variantSku)
{
var itemsToRemove = items.Where(x => x.Variant.VariantSku == variantSku).ToArray();
foreach(var item in itemsToRemove)
{
item.Order = null;
items.Remove(item);
}
}
它不起作用,因为IList没有这个方法
我试过:
items.ToList().RemoveAll(x => x.Variant.VariantSku == variantSku);
但这似乎不起作用。我意识到items.ToList()
实际上创建了原始列表的副本,因此我想我可以尝试:
var itemsList = items.ToList();
itemsList.RemoveAll(...)
但它是否仍然通过NHibernate持续存在
我的问题:在这种情况下,我是否可以使用
.RemoveAll
,或者我是否应该考虑以不同的方式删除项目?您始终可以创建自己的RemoveAll
扩展方法:
public static void RemoveAll<T>(this IList<T> source, Predicate<T> predicate)
{
// TODO: Argument non-nullity validation
// Optimization
List<T> list = source as List<T>
if (list != null)
{
list.RemoveAll(predicate);
return;
}
// Slow way
for (int i = source.Count - 1; i >= 0; i--)
{
if (predicate(source[i]))
{
source.RemoveAt(i);
}
}
}
publicstaticvoidremoveall(此IList源,谓词)
{
//TODO:参数非空性验证
//优化
列表=源作为列表
如果(列表!=null)
{
list.RemoveAll(谓词);
返回;
}
//慢行
对于(int i=source.Count-1;i>=0;i--)
{
if(谓词(源[i]))
{
资料来源:RemoveAt(i);
}
}
}
我希望NHibernate关心收藏本身——仅仅从列表中删除一个项目是NHibernate无法“注意到”的
当然,如果您不想让NHibernate关心您所做的事情—如果您的更改只是本地的—那么您的最后一段代码就可以了。您将集合映射为关系的反面,因此,除了从集合中删除项目外,还必须在OrderItem端取消对订单的引用。因此,RemoveAll方法或扩展方法无法完成此任务
我会这样处理:
public virtual IList<OrderItem> Items { get; set; }
public virtual void RemoveItem(string variantSku)
{
var itemsToRemove = items.Where(x => x.Variant.VariantSku == variantSku).ToArray();
foreach(var item in itemsToRemove)
{
item.Order = null;
items.Remove(item);
}
}
我还建议使用集合而不是包映射。Aha,因此标记“C#”吸引了伟大的Jon Skeet,也就是堆栈大师,他自己。。。很高兴知道:)。。。我确实需要NHibernate知道是否关心此操作。@autonomatt:在这种情况下,假设返回的集合乐于使用RemoveAt
删除项,这应该可以。我不确定您是否需要item.Order=null(如果您在映射中有.Cascade.AllDeleteOrphan()),是吗?这不是AllDeleteOrphan()的功能吗?不过,其余的都是恰到好处的。我犯了一个小学生的错误,就是对项目进行了预处理并试图删除。item.Order=null使其成为孤立项,否则在刷新会话时会重新保存。实际上,您的代码不起作用。您仍然会收到一个异常:“集合已修改;枚举操作可能无法执行。”我最终使用了for循环。ToArray应将元素复制到新数组中,以防止出现您看到的错误。