Fluent NHibernate:使用 CheckList 测试集合映射
我在一些项目中使用了 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 方法添加的,该方法确保 Ocorrencia 对 Intervencao 的引用“点”参考奥科伦西亚。现在,如何测试与 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 列表。如果我删除外部密钥,那么测试工作正常,但我相信我不应该这样做。
我可能做错了什么,但我不确定那是什么。那么,有人可以好心地告诉我如何解决这个问题吗?
谢谢你们。 路易斯
I've used Fluent NH in some projects but I'm having some problems with using the PersistenceSpecification class for testing a collection mapping. Here's the code for my classes (I'm just putting here the collection definition):
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; }
}
And here's the mappings (only the important things):
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();
}
}
As you can see, Interncao objects are added through the ModificaEstado method which ensures that Ocorrencia reference on Intervencao "points" to a reference of Ocorrencia. Now, how do I test this relationship with the PersistenceSpecification object? I've ended up with the following code:
[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();
}
}
}
Since IdOcorrencia is defined as an external key in table Intervencoes, the previous code fails because it tries to insert the intervencoes list with IdOcorrencia set to null. If I remove the external key, then the test works fine, but I believe that I shouldn't be doing that.
I'm probably doing something wrong but I'm not sure on what that is. So, can anyone be kind enough and give me a hint on how to solve this?
thanks guys.
Luis
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题是我使用的是旧版本的 Fluent nhibernate。最近的版本具有可让您解决此类问题的覆盖:
http ://www.mail-archive.com/[电子邮件受保护]/msg06121.html
The problem was that I was using an old version of the fluent nhibernate. recente versions have overrides which let you solve this kind of problem:
http://www.mail-archive.com/[email protected]/msg06121.html