我正在使用this article在我的两个对象Site
和WebOptions
之间建立一对一的关系。网站已经存在。 WebOptions中的记录可能存在也可能不存在。如果是,我的映射工作正常。如果不是,我的系统就会试图创建新记录。
这是我的网站类(重要位)
public class Site : CoreObjectBase
{
public virtual int SiteId { get; set; }
public virtual WebOptions WebOptions { get; set; }
}
这是我的网页选项类(重要部分)
public class WebOptions : CoreObjectBase
{
public virtual int WebOptionsId { get; set; }
private int SiteId { get; set; }
private Site Site { get; set; }
}
Site
的映射是
HasOne<WebOptions>(x => x.WebOptions)
.Cascade.All();
WebOptions
的映射是
Id(Reveal.Property<WebOptions>("SiteId")).GeneratedBy.Foreign("Site");
HasOne<Site>(Reveal.Member<WebOptions, Site>("Site"))
.Constrained()
.ForeignKey();
在数据中,Site后面的表没有WebOptions的foreighn键字段,但WebOptions后面的表包含SiteId。在我的代码中,我已经获得了该网站并使用site.WebOptions.SomeSetting
并希望保持这种方式。
我的问题是这个。如果我完全偏离了这个映射,我的模型就会中断,并且当几个记录保存到weboptions表中时,不会返回任何weboptions(重复)。但是,当我尝试保存新的WebOptions
对象时,我得到了
批量更新从更新返回了意外的行数;实际行 数:0;预期:1
我有一个包含2个保存方法的存储库类:
public sealed class Repository<T> : IRepository<T> where T : CoreObjectBase
{
public void SaveWithDependence<K>(T entity, K dependant) where K : CoreObjectBase
{
entity.Validate();
dependant.Validate();
using (ITransaction tx = Session.BeginTransaction())
{
Session.SaveOrUpdate(entity);
Session.SaveOrUpdate(dependant);
tx.Commit();
}
}
public void Save(T entity)
{
entity.Validate();
using (ITransaction tx = Session.BeginTransaction())
{
Session.SaveOrUpdate(entity);
tx.Commit();
}
}
}
如果找不到WebOptions
,我在制作新的时候会这样做:
var options = site.WebOptions;
if (options == null)
{
options = new WebOptions(site);
site.WebOptions = options;
}
构造函数看起来像这样设置私有变量
public WebOptions(Site site)
{
Site = site;
SiteId = site.SiteId;
}
然后保存,我试着跟随:
siteRepository.Save(site);
和
siteRepository.SaveWithDependence(site, options);
和
optionsRepository.Save(options);
和
optionsRepository.SaveWithDependence<Site>(options, site);
所有这些都返回上述错误。我的会话声明如下所示
sessionFactory =
Fluently.Configure().Database(
FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2005.DefaultSchema("dbo")
.ConnectionString(c => c
.FromConnectionStringWithKey("MyDatabase"))
.AdoNetBatchSize(20))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<SessionManager>())
.ExposeConfiguration(x => x.SetProperty("current_session_context_class", "managed_web"))
.BuildSessionFactory();
如果一条记录不存在,我真的需要能够保存一条新的WebOptions
记录,但我似乎无法通过我的一对一关系来处理它。
答案 0 :(得分:1)
在WebOptions
的构造函数中,我删除了这一行:
SiteId = site.SiteId;
对于看起来像这样的构造函数:
public WebOptions(Site site)
{
Site = site;
}
然后,我只保存我的WebOptions
对象:
optionsRepository.Save(options);
我最好的猜测是,因为我使用流利的'SiteId'属性的ID字段,所以我不能手动设置该值。除了设置Site
属性之外,设置私有属性Site.WebOptions
必须为fluent / nhibernate设置一对一关系,以推断出要放入SiteId字段的值。
对上面发布的文章的进一步检查表明,这是必须要做的。我碰巧错过了这条非常重要的信息:
公共构造函数,带有
Client
参数,只要您想为客户端分配一些营养习惯,就会在代码中使用该参数,例如:{{1} }。受保护的构造函数由NHibernate在内部使用,并且必须存在。你可以完全忽略它。
如果其他人有这个问题,我将离开这篇文章并回答,我可以节省一些时间和挫折。