无法在一对一关系中保存新对象

本文关键字:新对象 对象 保存 一对一 关系 | 更新日期: 2023-09-27 18:08:38

我使用本文在我的两个对象SiteWebOptions之间建立一对一的关系。网站已存在。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内部使用,并且必须存在。你可以完全忽略它。

如果其他人有这个问题,我会离开这个职位并回答,我可以为他们节省一点时间和沮丧。