一部のプロジェクトで Fluent NH を使用しましたが、コレクション マッピングをテストするために PersistenceSpecification クラスを使用すると問題が発生します。これが私のクラスのコードです(ここにコレクション定義を入れているだけです):
public class Ocorrencia : EntityWithAction, IHasAssignedId<Int32> {
private IList<Intervencao> _intervencoes = new List<Intervencao>();
public IEnumerable<Intervencao> Intervencoes {
get{
return new ReadOnlyCollection<Intervencao>( _intervencoes );
}
set {
_intervencoes = new List<Intervencao>( value );
Contract.Assume(_intervencoes != null);
}
}
public void ModificaEstado(Intervencao intervencao ){
//some checks removed
intervencao.Ocorrencia = this;
_intervencoes.Add(intervencao);
}
//more code removed
}
public class Intervencao : EntityWithAction, IHasAssignedDomainAction {
//other code remove
internal Ocorrencia Ocorrencia { get; set; }
}
そして、ここにマッピングがあります(重要なもののみ):
public class IntervencaoMapping: ClassMap<Intervencao> {
public IntervencaoMapping()
{
WithTable("Intervencoes");
Not.LazyLoad();
Id(intervencao => intervencao.Id)
.ColumnName("IdIntervencoes")
.WithUnsavedValue(0)
.SetGeneratorClass("identity");
Map(intervencao => intervencao.Guid, "Guid")
.Not.Nullable();
Version(ent => ent.Version)
.ColumnName("Version");
References(ent => ent.Action, "IdAccao")
.Cascade
.SaveUpdate();
Map(intervencao => intervencao.TipoEstado, "TipoEstado")
.CustomTypeIs(typeof (TipoEstado))
.CustomSqlTypeIs("integer");
Map(intervencao => intervencao.Observacoes, "Observacoes");
References(intervencao => intervencao.Ocorrencia, "IdOcorrencias")
.Not.LazyLoad();
}
}
public class OcorrenciaMapping: ClassMap<Sra.Ocorrencias.Ocorrencia> {
public OcorrenciaMapping()
{
WithTable("Ocorrencias");
Not.LazyLoad();
Id(ocorrencia => ocorrencia.Id)
.ColumnName("IdOcorrencias")
.WithUnsavedValue(0)
.SetGeneratorClass("identity");
Map(ocorrencia => ocorrencia.Guid, "Guid")
.Not.Nullable();
Version(ocorrencia => ocorrencia.Version)
.ColumnName("Version");
Map(ocorrencia => ocorrencia.Descricao)
.ColumnName("Descricao");
Map(ocorrencia => ocorrencia.Nif, "Nif")
.Not.Nullable();
Map(ocorrencia => ocorrencia.TipoOcorrencia, "TipoOcorrencia")
.CustomTypeIs(typeof(TipoOcorrencia))
.CustomSqlTypeIs("integer");
Map(ocorrencia => ocorrencia.BalcaoEntrada, "Balcao")
.CustomTypeIs(typeof(TipoBalcao))
.CustomSqlTypeIs("integer")
.Not.Nullable();
References(ocorrencia => ocorrencia.Organismo, "IdOrganismos")
.Cascade.None()
.Not.Nullable();
HasMany(ocorrencia => ocorrencia.Intervencoes)
.Access.AsCamelCaseField(Prefix.Underscore)
.AsBag()
.Cascade
.All()
.KeyColumnNames.Add("IdOcorrencias")
.Not.LazyLoad();
}
}
ご覧のとおり、Interncao オブジェクトは ModificaEstado メソッドによって追加されます。これにより、Intervencao の Ocorrencia 参照が Ocorrencia の参照を「指す」ようになります。さて、この PersistenceSpecification オブジェクトとの関係をテストするにはどうすればよいでしょうか? 私は次のコードで終わった:
[Test]
public void Test() {
using (var session = _factory.GetSession()) {
using (var tran = session.BeginTransaction()) {
var accao = CreateAction();
session.Save(accao);
var organismo = CreateOrganismo();
session.Save(organismo);
var intervencao = CreateIntervencao();
((IHasAssignedDomainAction)intervencao).SetActionTo(accao);
var intervencoes = new List<Intervencao> {intervencao};
new PersistenceSpecification<Ocorrencia>(session)
.CheckProperty(e => e.Nif, _nif)
.CheckProperty( e =>e.Organismo, organismo)
.CheckProperty( e => e.Descricao, _descricao)
.CheckProperty( e => e.TipoOcorrencia, TipoOcorrencia.Processo)
.CheckList( e => e.Intervencoes, intervencoes)
.VerifyTheMappings());
tran.Rollback();
}
}
}
IdOcorrencia はテーブル Intervencoes で外部キーとして定義されているため、前のコードは IdOcorrencia を null に設定して intervencoes リストを挿入しようとするため失敗します。外部キーを削除すると、テストは正常に機能しますが、そうすべきではないと思います。
私はおそらく何か間違ったことをしているのですが、それが何であるかはわかりません。それで、誰か親切で、これを解決する方法についてのヒントを教えてもらえますか?
みんなありがとう。ルイス