【问题标题】:c# allow duplicate in list.addc# 允许 list.add 中的重复
【发布时间】: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 类是如何工作的或如何将事物添加到数据库中。
  • 如果您在谈论 HashSetDictionary 的密钥,这是有道理的,但 List 类具有没有用于防止重复的功能(在 Add 期间基于 Equals、引用相等或其他任何内容。
  • 什么是EquatableObject&lt;T&gt;?无论哪种方式,仍然没有阻止您将多个项目添加到List&lt;T&gt; 的代码。您需要给我们一个minimal reproducible example
  • 阅读Add的代码。它对传入的item 所做的唯一一件事就是将它放在后备数组中。
  • @gt.guybrush System.Collections.Generric.List&lt;T&gt; 允许重复。这不讨论。另一方面,public virtual ICollection&lt;Allegato&gt; Allegati不是List&lt;T&gt;,即使它的原始值是List&lt;T&gt;。 NHiberrnate 将用自己的实现替换它以允许延迟加载。 那个实现不允许具有相同主键的条目,因为这显然是无效的

标签: c# collections nhibernate


【解决方案1】:

正如@Panagiotis Kanavos 所说,问题在于 NHibernate 用 Set 集合覆盖我的属性。我将地图更改为 Bag 以使其工作

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-03
    • 2011-07-17
    • 2010-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多