添加第一个新项目时,Nhibernate会从AsSet集合中丢失先前的项目

时间:2017-02-02 14:39:25

标签: c# nhibernate set

我有一个Nhibernate集合映射asSet的问题,当我向集合中添加新项目时,所有其他项目都丢失了。

但更奇怪的是,那些只添加一次,每次后续插入都没有问题,因为我重启app

这是我的对象:

    public class Attivita : BaseObject<Attivita, int> { 
    public override int Id { get; set; }
    private ICollection<SAL> _statiAvanzamentoLavori = new List<SAL>();
    public virtual IEnumerable<SAL> StatiAvanzamentoLavori { 
        get { return _statiAvanzamentoLavori.ToArray(); } 
    }

    public virtual void AddSAL(DateTime dataRiferimento, DateTime dataAvvioPrevisto, DateTime dataConclusionePrevista) {
        if (!(_statiAvanzamentoLavori.Any(x => x.DataRiferimento == dataRiferimento))){ 
            SAL sal = new SAL{ 
                DataRiferimento = dataRiferimento,
                DataAvvioPrevisto = dataAvvioPrevisto,
                DataConclusionePrevista = dataConclusionePrevista,            
            };
            _statiAvanzamentoLavori.Add(sal);
            }
        }
    }

public class SAL : EquatableObject<SAL>
{
    protected internal virtual int id {get; set;}
    public virtual DateTime DataRiferimento {get; set;}
    public virtual DateTime DataAvvioPrevisto {get; set;}
    public virtual DateTime DataConclusionePrevista {get; set;}

}

BaseObject使用ID属性

覆盖等于

EquatableObject override等于比较所有对象属性

地图:

public AttivitaMap()
    {
        Table("Attivita_T041");
        Id(x => x.Id)
            .Column("Kint_T041_IdAttivita").GeneratedBy.Assigned();
        HasMany<SAL>(x => x.StatiAvanzamentoLavori)
        .Access.CamelCaseField(Prefix.Underscore)
        .KeyColumns.Add("int_T018_IdAttivita", x => x.UniqueKey("IX18_1"))
        .ForeignKeyConstraintName("FK18_IdAtt") .Not.LazyLoad().Cascade.All();
    }
}

public SALMap()
{
    Table("SAL_T018");

    Id(x => x.id)
        .Column("Kint_T018_IdSAL")              
        .GeneratedBy.Identity();

    Map(x => x.DataRiferimento).UniqueKey("IX18_1")
            .Not.Nullable();
    Map(x => x.DataAvvioPrevisto);
    Map(x => x.DataConclusionePrevista).Not.Nullable();
}

最后测试:

[Test]      
public void AttivitaRepositoryCanInsertSALOnNotEmptyCollection()   {            
    var attivita = fixture.Create<Attivita>();
    var SAL1 = fixture.Create<SAL>();
    var SAL2 = fixture.Create<SAL>();

    attivita.AddSAL(SAL1.DataRiferimento, SAL1.DataAvvioPrevisto, SAL1.DataConclusionePrevista);
    using (UnitOfWork uow = GetUnitOfWork()) {
        uow.Attivita.Update(attivita);
        uow._session.Transaction.Commit();
    }

    using (UnitOfWork uow = GetUnitOfWork()) {
        attivita = uow._session.Get<Attivita>(attivita.Id);
        // this test pass
        attivita.StatiAvanzamentoLavori.Count().Should().Be(1); 
        attivita.AddSAL(SAL2.DataRiferimento, SAL2.DataAvvioPrevisto, SAL2.DataConclusionePrevista, SAL2.StatoAvanzamentoAttivita);
        uow.Attivita.Update(attivita);
        uow._session.Transaction.Commit();
    }

    using (UnitOfWork uow = GetUnitOfWork()) {              
        // this test fails: expected 2 found 1      
        uow._session.Get<Attivita>(attivita.Id).StatiAvanzamentoLavori.Count().Should().Be(2); 

var SAL3 = fixture.Build<SAL>().With(x => x.StatoAvanzamentoAttivita, statoAvanzamentoTest).Create();
using (UnitOfWork uow = GetUnitOfWork()) {
    attivita = uow._session.Get<Attivita>(attivita.Id); 
    attivita.AddSAL(SAL3.DataRiferimento, SAL3.DataAvvioPrevisto, SAL3.DataConclusionePrevista, SAL3.StatoAvanzamentoAttivita);
    uow.Attivita.Update(attivita);
    uow._session.Transaction.Commit();
}
using (UnitOfWork uow = GetUnitOfWork()) {
    uow._session.Get<Attivita>(attivita.Id).StatiAvanzamentoLavori.Count().Should().Be(3);  

 // this test fails: expected 3 found 2         
}

    }
}

所以当我添加第二个sal时,第一个丢失,但是当我添加第三个时,第二个仍然存在,为什么?

查看SQL日志我看到,当我添加第二个SAL时,更新被激活到SAL TABLE设置IdAttivita为NULL,因此链接到Attivita丢失

我阅读here删除和插入所有链接的行为是设计与Bag集合但我有SET与主键

如果我将AsSet更改为AsBag(或简单地删除AsAet)以进行集合映射,一切正常,但我需要设置其他内容(例如多次获取),这更奇怪

1 个答案:

答案 0 :(得分:0)

正如Nhibernate开发人员在他们的bugtracker问题上所回答的那样是混合Equals方法:Value对象必须通过他们的属性和实体进行比较

我的错是使用与实体SAL的peropery比较

所以我开始使用BaseObject,一切正常