NHibernate级联保存 [英] NHibernate cascading save

查看:85
本文介绍了NHibernate级联保存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这正在尝试将null插入Comment.BlogArticleID.

This is trying to insert null into Comment.BlogArticleID.

出现以下GenericADOException: 无法插入:[NHibernate__OneToMany.BO.Comment] [SQL:插入注释(名称)值(?);选择SCOPE_IDENTITY()]"

The following GenericADOException appeared: "could not insert: [NHibernate__OneToMany.BO.Comment][SQL: INSERT INTO Comment (Name) VALUES (?); select SCOPE_IDENTITY()]"

出现以下内部异常: 无法将值NULL插入表'Relationships_Test_OneToMany.dbo.Comment'的列'BlogArticleID'中;该列不允许为空.INSERT失败.\ r \ n该语句已终止."

The following Inner-Exception appeared: "Cannot insert the value NULL into column 'BlogArticleID', table 'Relationships_Test_OneToMany.dbo.Comment'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated."

我需要单向映射.提供的答案是关于双向映射的.

I need a unidirectional mapping. The answer provided yet is talking about bi-directional mapping.

NHibernate级联保存是否可以与本机ID生成器一起使用?

Does NHibernate cascade save works with native ID generator?

BlogArticle {ID,Name},如果是ID,则Identitity = true.

BlogArticle{ID, Name}, where in case of ID, Identitity=true.

注释{ID,名称,BlogArticleID},如果是ID,则Identitity = true.

Comment{ID, Name, BlogArticleID}, where in case of ID, Identitity=true.

<hibernate-mapping
  xmlns="urn:nhibernate-mapping-2.2"
  assembly="NHibernate__OneToMany.BO"
  namespace="NHibernate__OneToMany.BO"
  default-access="property">

  <class name="Comment" table="Comment">
    <id name="ID">
      <generator class="native" />
    </id>

    <property name="Name" />
  </class>
</hibernate-mapping>

public class Comment
    {
        private int _id;
        public virtual int ID
        {
            get { return _id; }
            set { _id = value; }
        }

        public Comment()
        {
        }

        public Comment(string name)
        {
            this._name = name;
        }

        private string _name;
        public virtual string Name
        {
            get { return _name; }
            set { _name = value; }
        }   
    }

BlogArticle.hbm.xml

<hibernate-mapping 
  xmlns="urn:nhibernate-mapping-2.2"
  namespace="NHibernate__OneToMany.BO"
  assembly="NHibernate__OneToMany.BO"
  default-access="property">
  <class name="BlogArticle"  table="BlogArticle">
    <id name="ID">
      <generator class="native" />
    </id>

    <property name="Name" column="Name" />

    <bag name="Comments" cascade="all" >
      <key column="BlogArticleID" />
      <one-to-many class="Comment" />
    </bag>
  </class>
</hibernate-mapping>


public class BlogArticle
    {
        private int _id;
        public virtual int ID
        {
            get { return _id; }
            set { _id = value; }
        }

        private string _name;
        public virtual string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        private IList _depts;
        public virtual IList Comments
        {
            get { return _depts; }
            set { _depts = value; }
        }   
    }

主要

class Program
{
    static void Main(string[] args)
    {
        BlogArticle ba = new BlogArticle();
        ba.Name = "Humanity";
        ba.Comments = new List<Comment>();
        ba.Comments.Add(new Comment("Comm1"));
        ba.Comments.Add(new Comment("Comm2"));
        ba.Comments.Add(new Comment("Comm3"));

        Repository<BlogArticle> rep = new Repository<BlogArticle>();
        rep.Save(ba);
    }
}

存储库

public class Repository<T> : IRepository<T>
    {
        ISession _session;

        public Repository()
        {
            _session = SessionFactoryManager.SessionFactory.OpenSession();
        }

        private void Commit()
        {
            if (_session.Transaction.IsActive)
            {
                _session.Transaction.Commit();
            }
        }

        private void Rollback()
        {
            if (_session.Transaction.IsActive)
            {
                _session.Transaction.Rollback();
                //_session.Clear();
            }
        }

        private void BeginTransaction()
        {
            _session.BeginTransaction();
        }

        public void Save(T obj)
        {
            try
            {
                this.BeginTransaction();

                _session.Save(obj);                

                this.Commit();
            }
            catch (Exception ex)
            {
                this.Rollback();

                throw ex;
            }            
        }

        void IRepository<T>.Save(IList<T> objs)
        {
            try
            {
                this.BeginTransaction();

                for (Int32 I = 0; I < objs.Count; ++I)
                {
                    _session.Save(objs[I]);
                }

                this.Commit();
            }
            catch (Exception ex)
            {
                this.Rollback();

                throw ex;
            }
        }

        void IRepository<T>.Update(T obj)
        {
            try
            {
                this.BeginTransaction();

                _session.Update(obj);

                this.Commit();
            }
            catch (Exception ex)
            {
                this.Rollback();

                throw ex;
            }
        }

        void IRepository<T>.Update(IList<T> objs)
        {
            try
            {
                this.BeginTransaction();

                for (Int32 I = 0; I < objs.Count; ++I)
                {
                    _session.Update(objs[I]);
                }

                this.Commit();
            }
            catch (Exception ex)
            {
                this.Rollback();

                throw ex;
            }
        }

        void IRepository<T>.Delete(T obj)
        {
            try
            {
                this.BeginTransaction();

                _session.Delete(obj);

                this.Commit();
            }
            catch (Exception ex)
            {
                this.Rollback();

                throw ex;
            }  
        }

        void IRepository<T>.Delete(IList<T> objs)
        {
            try
            {
                this.BeginTransaction();

                for (Int32 I = 0; I < objs.Count; ++I)
                {
                    _session.Delete(objs[I]);
                }

                this.Commit();
            }
            catch (Exception ex)
            {
                this.Rollback();

                throw ex;
            }
        }

        T IRepository<T>.Load<T>(object id)
        {
            return _session.Load<T>(id);
        }

        public IList<T> Get<T>(int pageIndex, int pageSize)
        {
            ICriteria criteria = _session.CreateCriteria(typeof(T));
            criteria.SetFirstResult(pageIndex * pageSize);
            if (pageSize > 0)
            {
                criteria.SetMaxResults(pageSize);
            }
            return criteria.List<T>();
        }

        public T Get<T>(object id)
        {
            return _session.Get<T>(id);
        }

        public IList<T> Get<T>()
        {
            return Get<T>(0, 0);
        }

        public IList<T> Get<T>(string propertyName, bool Ascending)
        {
            Order cr1 = new Order(propertyName, Ascending);

            IList<T> objsResult = _session.CreateCriteria(typeof(T)).AddOrder(cr1).List<T>();

            return objsResult;
        }

        public IList<T> Find<T>(IList<string> strs)
        {
            System.Collections.Generic.IList<NHibernate.Criterion.ICriterion> objs = new System.Collections.Generic.List<ICriterion>();
            foreach (string s in strs)
            {
                NHibernate.Criterion.ICriterion cr1 = NHibernate.Criterion.Expression.Sql(s);
                objs.Add(cr1);
            }
            ICriteria criteria = _session.CreateCriteria(typeof(T));
            foreach (ICriterion rest in objs)
                _session.CreateCriteria(typeof(T)).Add(rest);

            criteria.SetFirstResult(0);
            return criteria.List<T>();
        }

        public void Detach(T item)
        {
            _session.Evict(item);
        }        
    }

推荐答案

关联类的键列(Comment.BlogArticleID)在数据库中必须为空. NHibernate会插入使该列为NULL的行,然后执行更新以设置键.

The key column of the associated class (Comment.BlogArticleID) must be nullable in the database. NHibernate will insert rows leaving this column NULL and then perform an update to set the key.

将not-null ="true"添加到键元素将不起作用,因为此属性仅由架构导出工具使用.

Adding not-null="true" to the key element would not work, as this attribute is only used by the schema export tool.

请注意,失败的插入内容包括对新子行的生成身份的选择.

Note that the failing insert includes a select for the generated identity for the new child row.

这篇关于NHibernate级联保存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆