2014-03-26 72 views
6

我正在使用Envers來審計表,但它正在爲未知/缺少表創建一些審計表。 對於Many To One關係,它看起來像是多對多關係審覈表。NHibernate Envers:無法在對象中插入重複密鑰

這是正確的嗎?如果是這樣,爲什麼?

dbo.HorarioFixo - OK 
dbo.HorarioFixo_Auditoria - OK 
dbo.HorarioFixo_JanelaHorarioFixo_Auditoria - NOK 
dbo.JanelaHorarioFixo - OK 
dbo.JanelaHorarioFixo_Auditoria - OK 

但是,當我嘗試刪除/刪除和HorarioFixo我得到一個錯誤。

我得到的錯誤:

NHibernate.Exceptions.GenericADOException 
could not execute batch command.[SQL: SQL not available] 
    em NHibernate.Engine.ActionQueue.BeforeTransactionCompletionProcessQueue.BeforeTransactionCompletion() 
    em NHibernate.Impl.SessionImpl.BeforeTransactionCompletion(ITransaction tx) 
    em NHibernate.Transaction.AdoTransaction.Commit() 
    em Foo.Testes.Servicos.TesteCanalDeTransmissaoService.RemoveDependenciasCorretamente() na TesteCanalDeTransmissaoService.cs: line 195 
System.Data.SqlClient.SqlException 
Violation of PRIMARY KEY constraint 'PK__HorarioF__450088476960C81E'. Cannot insert duplicate key in object 'dbo.HorarioFixo_JanelaHorarioFixo_Auditoria'. 
Violation of PRIMARY KEY constraint 'PK__HorarioF__450088476960C81E'. Cannot insert duplicate key in object 'dbo.HorarioFixo_JanelaHorarioFixo_Auditoria'. 
The statement has been terminated. 
The statement has been terminated. 

這是複製的SQL:

exec sp_executesql N'INSERT INTO HorarioFixo_JanelaHorarioFixo_Auditoria (REVTYPE, REV, HorarioFixoId, JanelaHorarioFixoId) VALUES (@p0, @p1, @p2, @p3)',N'@p0 tinyint,@p1 int,@p2 bigint,@p3 bigint',@p0=2,@p1=3,@p2=1,@p3=2 go 

這一切是代碼的一部分。如果您需要更多信息,請發表評論。

我的課:

public class Entidade 
{ 
    protected Entidade(); 

    public virtual long Id { get; set; } 
    public virtual long Version { get; set; } 

    public abstract override bool Equals(object obj); 
    public override int GetHashCode(); 
} 

public class Horario : Entidade 
{ 
    protected Horario() 
    { 

    } 
} 

public class HorarioFixo : Horario 
{ 
    public virtual int Frequencia { get; set; } 

    public virtual ICollection<JanelaHorarioFixo> JanelasRemessa { get; set; } 

    public virtual ICollection<JanelaHorarioFixo> JanelasRetorno { get; set; } 
} 

public class JanelaHorarioFixo : Entidade 
{ 
    public virtual TimeSpan HorarioInicio { get; set; } 

    public virtual TimeSpan? HorarioLimite { get; set; } 
} 

我的映射:

public class HorarioMap : ClassMapping<Horario> 
{ 
    public HorarioMap() 
    { 
     Id(x => x.Id, mapper => 
     { 
      mapper.Generator(Generators.Identity); 
      mapper.UnsavedValue(0); 
     }); 
    } 
} 

public class HorarioFixoMap : JoinedSubclassMapping<HorarioFixo> 
{ 
    public HorarioFixoMap() 
    { 
     Property(x => x.Frequencia); 

     Bag(x => x.JanelasRemessa, m => 
     { 
      m.Cascade(Cascade.All); 
      m.Lazy(CollectionLazy.NoLazy); 
     }, map => map.OneToMany()); 

     Bag(x => x.JanelasRetorno, m => 
     { 
      m.Cascade(Cascade.All); 
      m.Lazy(CollectionLazy.NoLazy); 
     }, map => map.OneToMany()); 
    } 
} 

public class JanelaHorarioFixoMap : ClassMapping<JanelaHorarioFixo> 
{ 
    public JanelaHorarioFixoMap() 
    { 
     Id(x => x.Id, mapper => 
     { 
      mapper.Generator(Generators.Identity); 
      mapper.UnsavedValue(0); 
     }); 

     Property(x => x.HorarioInicio, m => m.NotNullable(true)); 

     Property(x => x.HorarioLimite, m => m.NotNullable(false)); 
    } 
} 

NH和Envers配置:

var ormHelper = ORMHelperUtils.GetORMHelper(); 

var mapper = new MyConventionModelMapper(); 

_config = new Configuration(); 

mapper.AddMappings(ormHelper.GetMappings()); 
mapper.AddMapping(typeof(REVINFOMap)); 
ormHelper.SetupApplicationNeeds(_config); 

_config.AddMapping(mapper.CompileMappingForAllExplicitlyAddedEntities()); 
_config.SetProperty(Environment.CurrentSessionContextClass, "call"); 

if (ormHelper.UseEnvers) 
{ 
    var classesDominio = ormHelper.GetDomainTables(); 

    if (classesDominio.Any()) 
    { 
     var envers = new FluentConfiguration(); 
     envers.Audit(classesDominio); 

     envers.SetRevisionEntity<REVINFO>(e => e.Id, e => e.Date, new CustomRevisionListener()); 

     _config.SetEnversProperty(ConfigurationKey.AuditTableSuffix, "_Auditoria"); 
     _config.IntegrateWithEnvers(envers); 
    } 
} 

回答

1

如果你使用一個單向到多,Envers需要一個鏈接表能有正確的歷史。

如果使用雙向一對多,則不需要鏈接表。

看到這個answer

4

我只是改變了我的班

public class HorarioFixo : Horario 
{ 
    public virtual int Frequencia { get; set; } 

    public virtual ICollection<JanelaHorarioFixo> Janelas { get; set; } 
} 

並向JanelaHorarioFixo添加了一個屬性來確定類型。但桌子dbo.HorarioFixo_JanelaHorarioFixo_Auditoria仍然在那裏,我不知道爲什麼。

相關問題