简体   繁体   English

如何在NHibernate中执行更新?

[英]How to execute update in NHibernate?

I'm trying execute update to object but it always throws an exception illegally attempted to associate a proxy with two open session . 我正在尝试执行对对象的更新,但是它总是会引发异常, illegally attempted to associate a proxy with two open session I can make insert but update I can't. 我可以插入,但不能更新。

How could I solve it ? 我该如何解决?

DBConnect 数据库连接

    public class DBConnect {

            private static ISessionFactory session;
            private const String HOST = "localhost";
            private const String USER = "root";
            private const String PASSWORD = "";
            private const String DB = "pubcontrol";

            /** create a connection with database */
            private static ISessionFactory createConnection() {

                if (session != null)
                    return session;

                //database configs
                FluentConfiguration _config = Fluently.Configure().Database(MySQLConfiguration.Standard.ConnectionString(
                                                                           x => x.Server(HOST).
                                                                              Username(USER).
                                                                              Password(PASSWORD).
                                                                              Database(DB)
                                                                            ))
                                                                            .Mappings(m => m.FluentMappings.AddFromAssemblyOf<PerfilMap>())
                                                                            .Mappings(m => m.FluentMappings.AddFromAssemblyOf<ModuloMap>())
                                                                            .Mappings(m => m.FluentMappings.AddFromAssemblyOf<PermissaoMap>())
                                                                            .ExposeConfiguration(cfg => new SchemaUpdate(cfg).Execute(false, true));

                session = _config.BuildSessionFactory();
                return session;
            }


            /** open a session to make transactions */
            public static ISession openSession() {
                return createConnection().OpenSession();
            }
        }

GenericDAO 通用DAO

public class GenericDAO<T> : IPersist<T> where T : class {

        public void insert(T obj) {
            ISession _session = DBConnect.openSession();
            ITransaction _transaction = _session.BeginTransaction();
            try {
                _session.Save(obj);
                _transaction.Commit();
            }catch (Exception e) {
                if (!_transaction.WasCommitted) {
                    _transaction.Rollback();
                }
                MessageBox.Show("Erro tentando salvar: " + e.Message, "Aviso",
                MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }


        public void update(T obj) {
            ISession _session = DBConnect.openSession();
            ITransaction _transaction = _session.BeginTransaction();
            try {
                _session.Update(obj);
                _transaction.Commit();
            }catch (Exception e) {
                if (!_transaction.WasCommitted) {
                    _transaction.Rollback();
                }
                MessageBox.Show("Erro tentando alterar: " + e.Message, "Aviso", 
                MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }



        public void delete(T obj) {
            ISession _session = DBConnect.openSession();
            ITransaction _transaction = _session.BeginTransaction();
            try {
                _session.Delete(obj);
                _transaction.Commit();
            }catch (Exception e) {
                if (!_transaction.WasCommitted) {
                    _transaction.Rollback();
                }
                MessageBox.Show("Erro tentando deletar: " + e.Message, "Aviso", 
                MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }



        public T findObject(long id) {
            ISession _session = DBConnect.openSession();
            return _session.Load<T>(id);
        }


        public void saveOrUpdate(T obj) {
            ISession _session = DBConnect.openSession();
            ITransaction _transaction = _session.BeginTransaction();
            try {
                _session.SaveOrUpdate(obj);
                _transaction.Commit();
            }catch (Exception e) {
                if (!_transaction.WasCommitted) {
                    _transaction.Rollback();
                }
                MessageBox.Show("Erro tentando salvar ou alterar: " + e.Message, "Aviso",
                MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }

PermissaoDAO 准证

public class PermissaoDAO : GenericDAO<Permissao> {

        public IList<Permissao> findAll() {
            ISession _session = DBConnect.openSession();
            IList<Permissao> list = _session.CreateQuery("FROM Permissao p")                
                .List<Permissao>();
            return list;
        }


        /** verifica se o perfil ou o modulo estao adicionados */
        public Boolean isExistPerfilAndModulo(Permissao permissao) {
            ISession _session = DBConnect.openSession();
            IList<Permissao> list = _session.CreateQuery("FROM Permissao p WHERE p.perfil = :p AND p.modulo = :m")
                .SetParameter("p", permissao.perfil)
                .SetParameter("m", permissao.modulo)
                .List<Permissao>();
            if (list.Count > 0) {
                return true;
            }
            return false;
        }

        /** retorna a permissao */
        public Permissao getPermissao(Permissao permissao) {
            ISession _session = DBConnect.openSession();
            IList<Permissao> list = _session.CreateQuery("FROM Permissao p WHERE p.perfil = :p AND p.modulo = :m").SetMaxResults(1)
                .SetParameter("p", permissao.perfil)
                .SetParameter("m", permissao.modulo)
                .List<Permissao>();
            return list[0];
        }


    }

Making Update 进行更新

/** insere Perfil + Modulo */
        private void insertPerfilModulo() {
            PermissaoDAO dao = new PermissaoDAO();
            Perfil perfil = (Perfil)cbxPerfilModulo.SelectedItem;
            IList<Modulo> lista = getListaModulo();

            foreach(Modulo m in lista){                
                Permissao permissao = new Permissao();
                permissao.perfil = perfil;
                permissao.modulo = m;

                Boolean exist = dao.isExistPerfilAndModulo(permissao);                
                if (exist) {
                    Permissao p = dao.getPermissao(permissao);
                    dao.update(p);
                }else {
                    dao.insert(permissao);
                }
            }
        }

You should not use multiple sessions with the same object. 您不应将多个会话与同一个对象一起使用。 You should not create a transaction for every single database operation, this way transaction do not make any sense. 您不应该为每个数据库操作都创建一个事务,这样事务就没有任何意义。 Have each a session and transaction span the whole business operation and don't forget to close (or dispose) both at the end. 每个会话和事务都涉及整个业务操作,并且不要忘记最后都将其关闭(或处置)。

Update is implicit for every object within the session. 会话中每个对象的更新都是隐式的。 Every object that had been queried or inserted is managed by the session. 会话管理已查询或插入的每个对象。

When using NHibernate, code usually looks like this (exemplary, can look very different depending on how you design your DAO, but the concept should be the same): 使用NHibernate时,代码通常看起来像这样(示例,根据您设计DAO的方式,看起来可能非常不同,但是概念应该相同):

using (session = dao.CreateSession())
using (session.CreateTransaction())
{
  var myObject = dao.Get<MyObject>(id);
  if (myObject == null)
  {
    myObject = new MyObject();
    dao.Insert(myObject);
  }
  myObject.Property = 3;
  dao.Commit();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM