【发布时间】:2021-10-25 08:41:53
【问题描述】:
我无法将重复元素添加到列表中
我想添加那个对象:
public class Allegato : BaseObject<Allegato, int>
{
public override int Id { get; set; }
public virtual string NomeFile { get; set; }
}
在 BaseObject 中我实现等于只查看 Id 字段
我无法更改此设置,因为我的 NHibernate 数据访问基础设施需要这些设置
现在我有一个包含Allegato 对象列表的其他类
public class Corso : BaseObject<Corso, int>
{
public virtual ICollection<Allegato> Allegati { get; set; } = new List<Allegato>();
public virtual void AddAllegato(Allegato allegato)
{
this.Allegati.Add(allegato);
}
}
现在我需要添加许多 Allegato 到集合中,然后将其保存到数据库中,ID 将为空,因为将由 DB 序列生成
using (myUow = myUowFactory.Create())
{
var obj = new Corso();
//populate corso
myUow.Corsi.Create(obj);
var files = SessionManagement.LeggiOggetto<SessionObject.File>(HttpContext, SessionManagement.ChiaveSessione.File);
foreach (var file in files)
obj.AddAllegato(new Allegato { NomeFile = file.Nome });
myUow.SaveAll();
}
添加了第一个对象,但其他所有对象都没有。第一个元素保留所有其他元素不添加
调试它看到Allegato类的equals方法被调用了,我该如何避免呢?
谢谢
编辑
基础对象类
public abstract class BaseObject<TEntity, TKey> : EquatableObject<TEntity>
where TEntity : class
{
public abstract TKey Id { get; set; }
public override int GetHashCode()
{
return Id.GetHashCode();
}
public override bool Equals(object obj)
{
if (obj == null)
return false;
BaseObject<TEntity, TKey> other = obj as BaseObject<TEntity, TKey>;
return BaseObjectEquals(other);
}
public override bool Equals(TEntity obj)
{
if (obj == null)
return false;
BaseObject<TEntity, TKey> other = obj as BaseObject<TEntity, TKey>;
return BaseObjectEquals(other);
}
public virtual bool BaseObjectEquals(BaseObject<TEntity, TKey> other)
{
if (other == null)
return false;
return EqualityComparer<TKey>.Default.Equals(this.Id , other.Id);
}
private IEnumerable<FieldInfo> GetFields()
{
Type t = GetType();
List<FieldInfo> fields = new List<FieldInfo>();
while (t != typeof(object))
{
fields.AddRange(t.GetTypeInfo().DeclaredFields.Where(x => x.FieldType.Name != typeof(ICollection<>).Name));//.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public));
t = t.GetTypeInfo().BaseType;
}
return fields;
}
public static bool operator ==(BaseObject<TEntity, TKey> x, BaseObject<TEntity, TKey> y)
{
// If both are null, or both are same instance, return true.
if (System.Object.ReferenceEquals(x, y))
{
return true;
}
// If one is null, but not both, return false.
if (((object)x == null) || ((object)y == null))
{
return false;
}
return x.Equals(y);
}
public static bool operator !=(BaseObject<TEntity, TKey> x, BaseObject<TEntity, TKey> y)
{
return !(x == y);
}
}
【问题讨论】:
-
没有什么可以阻止您在此处添加重复项,并且由于您没有显示完整的代码,因此我们无法提供太多帮助。我们不知道 BaseObject 是什么或它是如何工作的,我们不知道您的 UoW 类是如何工作的或如何将事物添加到数据库中。
-
如果您在谈论
HashSet或Dictionary的密钥,这是有道理的,但List类具有没有用于防止重复的功能(在Add期间基于 Equals、引用相等或其他任何内容。 -
什么是
EquatableObject<T>?无论哪种方式,仍然没有阻止您将多个项目添加到List<T>的代码。您需要给我们一个minimal reproducible example -
阅读
Add的代码。它对传入的item所做的唯一一件事就是将它放在后备数组中。 -
@gt.guybrush
System.Collections.Generric.List<T>允许重复。这不讨论。另一方面,public virtual ICollection<Allegato> Allegati不是List<T>,即使它的原始值是List<T>。 NHiberrnate 将用自己的实现替换它以允许延迟加载。 那个实现不允许具有相同主键的条目,因为这显然是无效的
标签: c# collections nhibernate