很久以前我已经在Fluent NH小组发布了这个,但直到今天才得到任何答案。那么,问题是:我已经定义了一对多的关系,并且一方设置了反向标志。映射代码如下所示:
public class MapeamentoReceita : ClassMap<Receita> {
public MapeamentoReceita() {
Table("Receitas");
Not.LazyLoad();
Id(rec => rec.Id, "IdReceita")
.GeneratedBy
.HiLo("TabelaHilo", "ProximoHi", "1000", "Tabela='receitas'")
.Default(0);
Version(rec => rec.Versao);
//other props go here
HasMany(rec => rec.Imagens)
.Access.CamelCaseField((Prefix.Underscore))
.AsBag()
.Cascade.All()
.KeyColumn("IdReceita")
.Not.LazyLoad()
.Inverse();
}
}
现在,Imagem的映射看起来像这样:
public class MapeamentoImagem : ClassMap<Imagem> {
public MapeamentoImagem() {
Table("Imagens");
Not.LazyLoad();
Id(img => img.Id, "IdImagem")
.GeneratedBy
.HiLo("TabelaHiLo", "ProximoHi", "1000", "Tabela='imagens'")
.Default(0);
Map(img => img.Bytes)
.CustomSqlType("image")
.CustomType<Byte[]>()
.LazyLoad()
.Length(2000000000)
.Not.Nullable()
.Not.Update();
References(img => img.Receita)
.Column("IdReceita")
.Cascade.None();
}
}
这是测试这些类持久性的代码:
new PersistenceSpecification<Receita>(sess)
.CheckList(rec => rec.Imagens,
_imagens,
(receita, imagem) => receita.AdicionaImagem(imagem))
.VerifyTheMappings();
即使Inverse处于“on”状态,PersistenceSpecification也会在插入Receita之前尝试插入Imagem。由于IdReceita是外键配置为不接受null,我最终得到一个例外。我已经尝试编写使用receita的“真实世界代码”并且它有效(我已经打开了SQL,我可以看到在这种情况下,Receita会在Imagem之前插入它应该是这样)。
由于没有人在FH小组回答这个问题,我想知道是否有人可以确认此PersistenceSpecification行为是一个错误。
感谢。
答案 0 :(得分:3)
你有没有尝试过这种方式?:
var receita = BuildMeAReceita();
var imagems = BuildSomeImagems();
foreach(var imagem in imagems){
receita.AdicionaImagem(imagem);
}
new PersistenceSpecification<Receita>(sess)
.VerifyTheMappings(receita);
答案 1 :(得分:0)
尝试:
References(img => img.Receita)
.Column("IdReceita")
.Not.Nullable();
我的猜测是你的真实世界代码首先保存Recieta,以便以正确的顺序发出插入。如果您更改了该代码以首先保存Imagem,则会出现相同的错误,因为NHibernate将尝试插入Imagem,然后使用外键更新它。
答案 2 :(得分:0)
您可以更改Imagem
References(img => img.Receita)
.Column("IdReceita")
.Cascade.SaveUpdate();
这将在Receita
Imagem
我发现PersistanceSpecification
适用于相当直接的关系,但如果您有复杂的对象图,则必须打开所有对象的级联。您的方案非常简单,但是这个小的更改应该允许您使用PersistanceSpecification
进行测试。
还要确保在AdicionaImagem
功能中设置图像的父级。这是一个例子:
public virtual void AdicionaImagem(Imagem newImagem)
{
newImagem.Receita = this;
imagems.Add(newImagem);
}
答案 3 :(得分:0)
您的代码中存在两个可能的问题。
session.Get<Imagem>(id);
)的简单加载导致
像这样的例外:
Invalid Cast (check your mapping for property type mismatches); setter of Imagem
。
解决方案是在Imagem上启用延迟加载或禁用字节属性上的延迟加载。以下是Receita和Imagem个实体,IEqualityComparer和PersistentSpecification代码段的实现。此代码适用于NH3.1和FNH 1.2。如果您的代码与这些代码段有所不同,请告诉我。