zoukankan      html  css  js  c++  java
  • NHibernate之(5):探索Insert, Update, Delete操作

    本节内容

    • 操作数据概述
    • 1.新建对象
    • 2.删除对象
    • 3.更新对象
    • 4.保存更新对象
    • 结语

      返回文章列表

    操作数据概述

    我们常常所说的一个工作单元,通常是执行1个或多个操作,对这些操作要么提交要么放弃/回滚。想想使用LINQ to SQL,一切的东西都在内存中操作,只有调用了DataContext.SubmitChanges()方法才把这些改变的数据提交到数据库中,LINQ to SQL那么提交要么回滚。

    我们使用NHibernate也一样,如果只查询数据,不改变它的值,就不需要提交(或者回滚)到数据库。

    注意:这节,我们在上一节源代码的基础上,在数据访问层中新建CustomerCRUD.cs类用于编写操作方法,在数据访问的测试层新建一CustomerCRUDFixture.cs类用于测试。

    1.新建对象

    简单描述:新建一个对象;调用ISession.Save();同步ISession。

    例子:在数据访问层编写CreateCustomer()方法,把传过来的Customer对象保存在数据库中。

    public int CreateCustomer(Customer customer)
    {
        int newid = (int)_session.Save(customer);
        _session.Flush();
        return newid;
    }
    public Customer GetCustomerById(int customerId)
    {
        return _session.Get<Customer>(customerId);
    }

    我们测试这个方法,新建一个Customer对象,调用CreateCustomer()方法返回新插入的CustomerId,再次根据CustomerId查询数据库是否存在这个对象。

    [Test]
    public void CreateCustomerTest()
    {
        var customer = new Customer() { Firstname = "zhang", Lastname = "san" };
        int newIdentity = _crud.CreateCustomer(customer);
        var testCustomer = _crud.GetCustomerById(newIdentity);
        Assert.IsNotNull(testCustomer);
    }

    2.删除对象

    简单描述:获取一个对象;调用ISession.Delete();同步ISession。

    说明:使用ISession.Delete()会把对象的状态从数据库中移除。当然,你的应用程序可能仍然持有一个指向它的引用。所以,最好这样理解:Delete()的用途是把一个持久化实例变成临时实例。 你也可以通过传递给Delete()一个NHibernate 查询字符串来一次性删除很多对象。删除对象顺序没有要求,不会引发外键约束冲突。当然,有可能引发在外键字段定义的NOT NULL约束冲突。

    例子:在数据访问层编写DeleteCustomer()方法,从数据库中删除Customer对象。

    public void DeleteCustomer(Customer customer)
    {
        _session.Delete(customer);
        _session.Flush();
    }

    我们测试这个方法,在数据库中查询CustomerId为2的Customer对象,调用DeleteCustomer()方法删除,再次根据CustomerId查询数据库是否存在这个对象。

    [Test]
    public void DeleteCustomerTest()
    {
    int customerId=2; var coutomer = _crud.GetCustomerById(customerId); _crud.DeleteCustomer(coutomer); var testCustomer = _crud.GetCustomerById(customerId); Assert.IsNull(testCustomer); }

    3.更新对象

    简单描述:获取一个对象;改变它的一些属性;调用ISession.Update();同步ISession。

    例子:在数据访问层编写UpdateCustomer()方法,修改Customer对象。

    public void UpdateCustomer(Customer customer)
    {
        _session.Update(customer);
        _session.Flush();
    }

    测试这个方法,在数据库中查询CustomerId为1的Customer对象并修改它的Firstname属性值,调用UpdateCustomer()方法更新,再次查询数据库中CustomerId为1的Customer对象的Firstname值为修改之后的值。

    [Test]
    public void UpdateCustomerTest()
    {   
    int customerId = 1; var customer = _crud.GetCustomerById(customerId); customer.Firstname = "zhang"; _crud.UpdateCustomer(customer); var testCustomer = _crud.GetCustomerById(customerId); Assert.AreEqual("zhangsan", customer.Firstname); }

    4.保存更新对象

    你会不会想出这个问题?哪些是刚刚创建的对象,哪些是修改过的对象?对于刚刚创建的对象我们需要保存到数据库中,对于修改过的对象我们需要更新到数据库中。

    幸好,ISession可以识别出这不同的对象,并为我们提供了ISession.SaveOrUpdate(object)方法

    ISession.SaveOrUpdate(object)方法完成如下工作:

    • 检查这个对象是否已经存在Session中。
    • 如果对象不在,调用Save(object)来保存。
    • 如果对象存在,检查这个对象是否改变了。
    • 如果对象改变,调用Update(object)来更新。

    看看下面例子说明了这种情况,在数据访问层编写SaveOrUpdateCustomer()方法,保存更新Customer对象列表,依次遍历列表中的Customer对象,调用ISession.SaveOrUpdate(object)方法保存更新每个Customer对象。

    public void SaveOrUpdateCustomer(IList<Customer> customer)
    {
        foreach (var c in customer)
        {
            _session.SaveOrUpdate(c);
        }
        _session.Flush();
    }
    public IList<Customer> GetCustomersByFirstname(string firstname)
    {
        return _session.CreateCriteria(typeof(Customer))
            .Add(Restrictions.Eq("Firstname", firstname)) 
            .List<Customer>();
    }
            
    public IList<Customer> GetCustomersByFirstnameAndLastname(string firstname,string lastname)
    {
        return _session.CreateCriteria(typeof(Customer))
            .Add(Restrictions.Eq("Firstname", firstname))
            .Add(Restrictions.Eq("Lastname", lastname))
            .List<Customer>();
    }

    测试这个方法,先在数据库中查询Firstname为YJing的Customer对象并修改它的Lastname属性值,这些对象是数据库中存在的,并改变了,然后新建2个Customer对象,这两个对象在数据库中不存在,是新创建的。调用SaveOrUpdateCustomer()方法保存更新对象,即更新前面修改的对象和保存了后面新创建的2个对象。再次查询数据库中Firstname为YJing,Lastname为YongJing的Customer对象是否一致了。

    [Test]
    public void SaveOrUpdateCustomerTest()
    {
        IList<Customer> customers = _crud.GetCustomersByFirstname("zhang");
        foreach (var c in customers)
        {
            c.Lastname = "san";
        }
        var c1 = new Customer() { Firstname = "zhang", Lastname = "san"};
        var c2 = new Customer() { Firstname = "zhang", Lastname = "san"};
        customers.Add(c1);
        customers.Add(c2);
        int initiaIListCount = customers.Count;
    
        _crud.SaveOrUpdateCustomer(customers);
    
        int testListCount = _crud.GetCustomersByFirstnameAndLastname("zhang", "san").Count;
        Assert.AreEqual(initiaIListCount, testListCount);
    }

    结语

    当然,这一节操纵对象操作,在NHibernate中涉及了对象的状态,对象对一个特定的ISession来说,有三种状态分别是:瞬时(transient)对象、持久化(persistent)对象、游离(detached)对象。这一节没有说到了,以后在讨论Session的时候再介绍。

     

    NHibernate Q&A

    上一篇:NHibernate之(4):探索查询之条件查询(Criteria Query)

    下一篇:NHibernate之(6):探索NHibernate中的事务

  • 相关阅读:
    NodeJs学习历程
    MongoDb学习历程
    递归函数为什么要防止栈溢出
    *args 是可变参数,args 接收的是一个 tuple; **kw 是关键字参数,kw 接收的是一个 dict。
    list和tuple的区别
    python源码阅读
    常用的线程池有哪些?
    备份
    假设你正在爬楼梯,需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶,你有多少种不同的方法可以爬到楼顶呢?
    最后一个单词的长度
  • 原文地址:https://www.cnblogs.com/a282421083/p/13441636.html
Copyright © 2011-2022 走看看