无法以一对一的关系保存新对象

时间:2011-09-15 20:36:57

标签: c# nhibernate fluent-nhibernate one-to-one

我正在使用this article在我的两个对象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的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记录,但我似乎无法通过我的一对一关系来处理它。

1 个答案:

答案 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在内部使用,并且必须存在。你可以完全忽略它。

如果其他人有这个问题,我将离开这篇文章并回答,我可以节省一些时间和挫折。