无法在一对一关系中保存新对象
本文关键字:新对象 对象 保存 一对一 关系 | 更新日期: 2023-09-27 18:08:38
我使用本文在我的两个对象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的外键字段,但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
记录,我真的需要能够保存它,但我似乎无法将其用于我的一对一关系。
哇,我花了所有的时间把它们放在一起,然后在玩它的时候,我删除了一行代码——只是想看看会发生什么。
在WebOptions
的构造函数中,我删除了这一行:
SiteId = site.SiteId;
对于一个看起来像这样的构造函数:
public WebOptions(Site site)
{
Site = site;
}
然后,我只保存我的WebOptions
对象,如下所示:
optionsRepository.Save(options);
我的最佳猜测是,由于我在fluent中使用"SiteId"属性的ID字段,fluent不允许我手动设置该值。设置私有属性Site
除了设置Site.WebOptions
属性外,还必须为fluent/nhibernate设置一对一关系,以推断要放入SiteId字段的值。
对上述文章的进一步检查表明,这是必须的。我只是碰巧错过了这条非常重要的信息:
公共构造函数采用
Client
参数,当您想为客户端分配一些饮食习惯时,您将在代码中使用它,例如:AlimentaryHabits = new AlimentaryHabits(this);
。受保护的构造函数由NHibernate内部使用,并且必须存在。你可以完全忽略它。
如果其他人有这个问题,我会离开这个职位并回答,我可以为他们节省一点时间和沮丧。