我有一个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
)以进行集合映射,一切正常,但我需要设置其他内容(例如多次获取),这更奇怪
答案 0 :(得分:0)
正如Nhibernate开发人员在他们的bugtracker问题上所回答的那样是混合Equals方法:Value对象必须通过他们的属性和实体进行比较
我的错是使用与实体SAL的peropery比较
所以我开始使用BaseObject,一切正常