【问题标题】:Fluent NHibernate hasmany save insert null valueFluent NHibernate hasmany save insert null value
【发布时间】:2011-04-15 15:44:29
【问题描述】:

我是 nhibernate 的新手,所以反应可能取决于我缺乏知识。

我创建了这两个表:

(对不起意大利语,我希望你能理解没有任何问题)。

然后,我的模型中有这些对象:


[Serializable]
public class Profilo
{
    public virtual int Id { get; set; }
    public virtual string Matricola { get; set; }
    public virtual string Ruolo { get; set; }
    public virtual IList ListaSedi { get; set; }

    public Profilo()
    {
        ListaSedi = new List();
    }
}

[Serializable]
public class Sede
{
    public virtual string CodiceSede { get; set; }
    public virtual string DescrizioneSede { get; set; }
    public virtual Profilo Profilo { get; set; }
}

这是我使用 fluent nhibernate 映射实体的方式:


    public class Map_Sede : FluentNHibernate.Mapping.ClassMap
    {
        public Map_Sede()
        {
            Table("TBA_Sede");

            Id(x => x.CodiceSede).Column("codice_sede").GeneratedBy.Assigned();

            Map(x => x.DescrizioneSede)
                .Column("descrizione");


            References(prof => prof.Profilo)
                .Column("codice_sede");

        }

    }


    public class Map_Profilo : FluentNHibernate.Mapping.ClassMap
    {
        public Map_Profilo()
        {
            Table("TBA_Profilo");

            Id(x => x.Id).Column("id").GeneratedBy.Identity();

            Map(x => x.Matricola)
                .Column("matricola");

            Map(x => x.Ruolo)
                .Column("ruolo");

            HasMany(x => x.ListaSedi)
                .AsBag()
                .KeyColumns.Add("codice_sede")
                .Not.LazyLoad()
                .Cascade.None();

        }
    }

现在,我想在我的上插入一个新的 Profilo 实例。一切似乎都正常,但 nhibernate 不会在 TBA_Profilo.codice_sede 列上插入值。我注意到插入语句由两个参数(matricola,ruolo)组成 - 为什么它忘记了第三个参数?

我在某处(在 nhibernate 邮件列表上)读到这很正常,因为 nhiberate 先用 null 插入值,然后用列表属性中包含的正确值更新相同的记录。

对吗? 我有什么错误吗?

我希望已经澄清了情况。 谢谢各位

ps:我正在使用 Nhibernate 2.1 和流利的 nhibernate 1.1

更新:这是我用来保存实体的代码。


                var sesionFactory = NHibernateHelper.createSessionFactory();

                using (NHibernate.ISession session = sesionFactory.OpenSession())
                {
                    using (var transaction = session.BeginTransaction())
                    {
                        try
                        {
                            session.SaveOrUpdate(entity);
                            transaction.Commit();
                            session.Flush();
                        }
                        catch (Exception)
                        {
                            transaction.Rollback();
                            throw;
                        }
                        finally
                        {
                            transaction.Dispose();
                        }
                    }
                }

更新 2:在狡猾的回答之后,我稍微修改了我的解决方案。这些是新的模型实体:



[Serializable]
public class Profilo
{
    public virtual int Id { get; set; }
    public virtual string Matricola { get; set; }
    public virtual string Ruolo { get; set; }
    public virtual IList ListaSedi { get; set; }

    public Profilo()
    {
        ListaSedi = new List();
    }
}

[Serializable]
public class Sede
{
    public virtual string CodiceSede { get; set; }
    public virtual string DescrizioneSede { get; set; }
    public virtual IList ProfiliAssociati { get; set; }
}

还有新的映射:


 public class Map_Sede : FluentNHibernate.Mapping.ClassMap
    {
        public Map_Sede()
        {
            Table("TBA_Sede");

            Id(x => x.CodiceSede).Column("codice_sede").GeneratedBy.Assigned();

            Map(x => x.DescrizioneSede)
                .Column("descrizione");


            HasMany(x => x.ProfiliAssociati)
                .AsBag()
                .KeyColumns.Add("codice_sede")
                .Cascade.All();


        }

    }


    public class Map_Profilo : FluentNHibernate.Mapping.ClassMap
    {
        public Map_Profilo()
        {
            Table("TBA_Profilo");

            Id(x => x.Id).Column("id").GeneratedBy.Identity();

            Map(x => x.Matricola)
                .Column("matricola");

            Map(x => x.Ruolo)
                .Column("ruolo");

            HasMany(x => x.ListaSedi)
                .AsBag()
                .Inverse()
                .KeyColumns.Add("codice_sede")
                .Cascade.SaveUpdate();

        }
    }

现在它似乎可以正常工作了:我的意思是 nhibernate 可以写入 TBA_Profilo.codice_sede 列,即使它没有在 Profilo.IList 上循环(它插入此列表的最后一个元素)。

有什么想法吗?

【问题讨论】:

    标签: c# nhibernate fluent-nhibernate nhibernate-mapping


    【解决方案1】:

    KeyColumns 映射仅应用于多对一连接中的子表。

    如果您想建立连接,您需要使用 TBA_portfolio 表中的 Id 列并从 TBA_Sede 引用它。

    类似这样的:

    Tba_portfolio id|matricola|ruolo

    tba_sede Id|PorfolioId|描述

    【讨论】:

    • 此外,我通过编写我用来保存实体的方法编辑了我的帖子
    • 我明白你的意思,但这种情况会与我的不同。我可以理解为什么 nhibernate 不能正确填充 TBA_Profilo.codice_sede :(
    【解决方案2】:

    你的映射错误,试试这个:

    public class Map_Profilo : FluentNHibernate.Mapping.ClassMap
        {
            public Map_Profilo()
            {
                Table("TBA_Profilo");
    
                Id(x => x.Id).Column("id").GeneratedBy.Identity();
    
                Map(x => x.Matricola)
                    .Column("matricola");
    
                Map(x => x.Ruolo)
                    .Column("ruolo");
    
                HasMany(x => x.ListaSedi)
                    .AsBag()
                    .KeyColumns.Add("codice_sede")
                    .Not.LazyLoad()
                    .Cascade.SaveUpdate();
    
            }
        }
    
    public class Map_Sede : FluentNHibernate.Mapping.ClassMap
    {
        public Map_Sede()
        {
            Table("TBA_Sede");
    
            Id(x => x.CodiceSede).Column("codice_sede").GeneratedBy.Assigned();
    
            Map(x => x.DescrizioneSede)
                .Column("descrizione");
    
    
            References(prof => prof.Profilo)
                .Column("codice_sede")
                .Cascade.None()
                .Inverse();
    
        }
    
    }
    

    关键是,您需要父配置文件来保存其子项。让子项对其父项不执行任何操作。此外,您的表格图看起来不对,profolio 不应该有 sede 的键,但 sede 应该有一个 fk 到 profolio。

    【讨论】:

    • 自从我从事该映射以来,它持续了很长时间。我真的不知道这是否应该是正确的解决方案。无论如何,谢谢你的回答;)
    猜你喜欢
    • 1970-01-01
    • 2011-02-27
    • 1970-01-01
    • 2012-04-03
    • 2013-04-24
    • 2012-10-19
    • 2011-12-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多