• Warensoft Unity3D通信库使用向导5对SQL SERVER进行增、删、改、查操作


    Warensoft Unity3D通信库使用向导5-对SQL SERVER进行增、删、改、查操作

    (作者:warensoft,有问题请联系warensoft@163.com)

    在前一节《warensoft unity3d通信库使用向导4-SQL Server访问组件说明》中已经对数据访问组件的结构做了简单的介绍,本节将说明如何具体利用这些组件对SQL SERVER进行操作。

    无论进行哪种操作,首先都要建立DataContext类的实例,建立方法如下所示:

    //通信管理器类
    
        private UnityCommunicationManager cm;
    
    //数据库连接管理器
    
        private DataContext context;
    
     
    
     
    
    public void Start()
    
    {
    
            //创建通信管理器的实例
    
    cm = UnityCommunicationManager.CreateInstance();
    
    //创建数据库连接管理器的实例,CreateDataContext中的参数就是数据服务的地址
    
    this.context = this.cm.CreateDataContext("http://localhost:20869/Web/Default.aspx");
    
            //注册Error事件,该事件会在数据库连接发生异常时触发
    
    this.context.Error+=new EventHandler<ErrorEventArgs>(this.OnContextError);
    
    //当指定的数据库中的数据表结构加载完毕时触发,该操作只加载表结构,不加载表中的数据
    
    this.context.SchemaLoadCompleted += new EventHandler(context_SchemaLoadCompleted);
    
    }

     

    代码说明:

    • DataContext类实例的构造过程要放在Start()方法中
    • DataContext类不能直接利用其构造函数构造,应用使用UnityCommunicationManager.CreateDataContext(string)方法构造,其参数就是数据服务的地址
    • DataContext中的Error事件,会在数据连接出现异常时触发
    • DataContext类在构造的时候,会向远程服务器发出请求以获取所要连接数据库的表结构。在表结构获取完毕之前,是不能对其进行任何数据操作的。DataContext中提供了一个SchemaLoadCompleted事件,该事件会在表结构加载完毕后触发。用户可以在该事件的回调该当中处理逻辑,该事件是在某一次Update()中被触发的,因此对于Unity3D来说,是线程安全的。另外,如果用户希望自己在C#脚本的Update()方法中控制DataContext以实现数据操作,可以使用DataContext类中的SchemaLoaded属性来判断表结构是否加载完毕。
    加载数据

    下面的代码描述了如何从服务器上获取tb_Students表中获取全部数据,并将其分页显示在Unity3D的GameView中,其完全内容如下所示:

     

    using System;
    
    using System.Collections.Generic;
    
    using System.Linq;
    
    using System.Text;
    
    using UnityEngine;
    
    using Warensoft.Unity.Communication.Client.DataClient;
    
    using Warensoft.Unity.Communication.Client;
    
    public class Paging : MonoBehaviour
    
    {
    
    UnityCommunicationManager cm;
    
    DataContext context;
    
    public void Start()
    
    {
    
    cm = UnityCommunicationManager.CreateInstance();
    
    this.context = this.cm.CreateDataContext("http://localhost/dataservice/Default.aspx");
    
    this.context.Error += new EventHandler<ErrorEventArgs>(this.OnContextError);
    
    this.context.SchemaLoadCompleted += new EventHandler(context_SchemaLoadCompleted);
    
    }
    
     
    
    void context_SchemaLoadCompleted(object sender, EventArgs e)
    
    {
    
    //加载表中所有记录
    
    this.context.Tables["tb_Students"].LoadAsync(() =>
    
    {
    
    //计算分页数量
    
    this.pageCount = this.context.Tables["tb_Students"].Count / this.pageCapacity;
    
    if (this.context.Tables["tb_Students"].Count%this.pageCapacity!=0)
    
    {
    
    this.pageCount++;
    
    }
    
    //通知OnGUI可以进行显示
    
    this.drawTable = true;
    
    });
    
    }
    
    public void OnContextError(object sender, ErrorEventArgs e)
    
    {
    
    print(e.Message);
    
    }
    
     
    
    private bool drawTable = false;
    
    private int pageNumber = 0;
    
    private int pageCapacity = 5;
    
    private int pageCount = 0;
    
    public void OnGUI()
    
    {
    
    if (this.drawTable)
    
    {
    
    //计算该分页中的数据
    
    var data = this.context.Tables["tb_Students"].Entities.
    
    Skip(this.pageNumber * this.pageCapacity).
    
    Take(this.pageCapacity );
    
    //绘制窗口
    
    GUI.Window(0, new Rect(0, 0, 400, 300), (id) =>
    
    {
    
    int row = 30;
    
     
    
    foreach (var entity in data)
    
    {
    
    //显示第一列,StudentName
    
    GUI.Label(new Rect(10, row, 100, 20), entity["StudentName"].ToString());
    
    //显示第二列,Age
    
    GUI.TextField(new Rect(100, row, 100, 20), entity["Age"].ToString());
    
    //显示第三列,Gender
    
    GUI.Label(new Rect(230, row, 60, 20), entity["Gender"].ToString() == "True" ? "Male" : "Female");
    
     
    
    row += 50;
    
    }
    
    //上翻页按钮
    
    if (GUI.Button(new Rect(80, 270, 80, 20), "Previous"))
    
    {
    
    if (this.pageNumber > 0)
    
    {
    
    this.pageNumber--;
    
    }
    
     
    
    }
    
    //下翻页按钮
    
    if (GUI.Button(new Rect(180, 270, 80, 20), "Next"))
    
    {
    
    if (this.pageNumber < this.pageCount - 1)
    
    {
    
    this.pageNumber++;
    
     
    
    }
    
     
    
    }
    
     
    
    }, "tb_Students");
    
     
    
    }
    
    }
    
    }

     

     

    GameView中的效果如下图所示:

    通过查询条件加载数据

    上面的代码是一次性将单表数据加载到客户的,这种处理方式可以提高分页时的速度,保证界面不出现闪烁。但是如果单表数据量很大的话,这种方案就不是一个好选择了,因此,可以采用带查询条件的加载方式,关于如何利用DataQuery类构建条件查询,请参考warensoft unity3d通信库使用向导4-SQL Server访问组件说明》,条件查询的完整代码如下所示:

    using System;
    
    using System.Collections.Generic;
    
    using System.Linq;
    
    using System.Text;
    
    using UnityEngine;
    
    using Warensoft.Unity.Communication.Client.DataClient;
    
    using Warensoft.Unity.Communication.Client;
    
    public class Paging : MonoBehaviour
    
    {
    
    UnityCommunicationManager cm;
    
    DataContext context;
    
    public void Start()
    
    {
    
    cm = UnityCommunicationManager.CreateInstance();
    
    this.context = this.cm.CreateDataContext("http://localhost:20869/Web/Default.aspx");
    
    this.context.Error += new EventHandler<ErrorEventArgs>(this.OnContextError);
    
    this.context.SchemaLoadCompleted += new EventHandler(context_SchemaLoadCompleted);
    
    }
    
     
    
    void context_SchemaLoadCompleted(object sender, EventArgs e)
    
    {
    
    //设置查询条件
    
    var query = new DataQuery();
    
    //加载表中所有记录
    
    this.context.Tables["tb_Students"].LoadAsync(() =>
    
    {
    
    //计算分页数量
    
    this.pageCount = this.context.Tables["tb_Students"].Count / this.pageCapacity;
    
    if (this.context.Tables["tb_Students"].Count%this.pageCapacity!=0)
    
    {
    
    this.pageCount++;
    
    }
    
    //通知OnGUI可以进行显示
    
    this.drawTable = true;
    
    },query.GreaterThanOrEqualsTo("Age",10).Take(50));
    
    }
    
    public void OnContextError(object sender, ErrorEventArgs e)
    
    {
    
    print(e.Message);
    
    }
    
     
    
    private bool drawTable = false;
    
    private int pageNumber = 0;
    
    private int pageCapacity = 5;
    
    private int pageCount = 0;
    
    public void OnGUI()
    
    {
    
    if (this.drawTable)
    
    {
    
    //计算该分页中的数据
    
    var data = this.context.Tables["tb_Students"].Entities.
    
    Skip(this.pageNumber * this.pageCapacity).
    
    Take(this.pageCapacity );
    
    //绘制窗口
    
    GUI.Window(0, new Rect(0, 0, 400, 300), (id) =>
    
    {
    
    int row = 30;
    
     
    
    foreach (var entity in data)
    
    {
    
    //显示第一列,StudentName
    
    GUI.Label(new Rect(10, row, 100, 20), entity["StudentName"].ToString());
    
    //显示第二列,Age
    
    GUI.TextField(new Rect(100, row, 100, 20), entity["Age"].ToString());
    
    //显示第三列,Gender
    
    GUI.Label(new Rect(230, row, 60, 20), entity["Gender"].ToString() == "True" ? "Male" : "Female");
    
     
    
    row += 50;
    
    }
    
    //上翻页按钮
    
    if (GUI.Button(new Rect(80, 270, 80, 20), "Previous"))
    
    {
    
    if (this.pageNumber > 0)
    
    {
    
    this.pageNumber--;
    
    }
    
     
    
    }
    
    //下翻页按钮
    
    if (GUI.Button(new Rect(180, 270, 80, 20), "Next"))
    
    {
    
    if (this.pageNumber < this.pageCount - 1)
    
    {
    
    this.pageNumber++;
    
     
    
    }
    
     
    
    }
    
     
    
    }, "tb_Students");
    
     
    
    }
    
    }
    
    }

     

    插入数据

    数据插入操作的过程,和利用DataSet+DataAdapter插入数据的方式很类似,其基本过程如下所示:

    1. 希望往哪个表中插入数据,就先利用该表创建一个新的实体,该实体不包含数据,但是和创建该实体所在的表具备相同的构架,代码如下所示:

      var newStudent=this.context.Tables["tb_Students"].NewEntity();

    2. 给新建立的实体中的属性赋值,代码如下所示:

      newStudent["ID"]=Guid.NewGuid();

      newStudent["Age"]=10;

      newStudent["Gender"]=false;

    3. 将新建立的实体加入实体集,代码如下所示:

      this.context.Tables["tb_Students"].Add(newStudent);

    4. 保存修改,提交到服务器,代码如下所示:

      this.context.SaveChanges();

    完整代码如下所示:

    using System;
    
    using System.Collections.Generic;
    
    using System.Linq;
    
    using System.Text;
    
    using UnityEngine;
    
    using Warensoft.Unity.Communication.Client.DataClient;
    
    using Warensoft.Unity.Communication.Client;
    
    public class Insert : MonoBehaviour {
    
        //通信管理器类
    
        private UnityCommunicationManager cm;
    
    //数据库连接管理器
    
        private DataContext context;
    
     
    
     
    
    public void Start()
    
    {
    
            //创建通信管理器的实例
    
    cm = UnityCommunicationManager.CreateInstance();
    
    //创建数据库连接管理器的实例,CreateDataContext中的参数就是数据服务的地址
    
    this.context = this.cm.CreateDataContext("http://localhost:20869/Web/Default.aspx");
    
            //注册Error事件,该事件会在数据库连接发生异常时触发
    
    this.context.Error+=new EventHandler<ErrorEventArgs>(this.OnContextError);
    
    //当指定的数据库中的数据表结构加载完毕时触发,该操作只加载表结构,不加载表中的数据
    
    this.context.SchemaLoadCompleted += new EventHandler(context_SchemaLoadCompleted);
    
    }
    
    public void OnContextError(object sender, ErrorEventArgs e)
    
    {
    
    print(e.Message);
    
    }
    
    void context_SchemaLoadCompleted(object sender, EventArgs e)
    
    {
    
     
    
    this.drawTable = true;
    
    }
    
          
    
    private bool drawTable = false;
    
     
    
        string age="";
    
        string gender="";
    
        string name="";
    
        void OnGUI()
    
        {
    
    //如果表结构已经加载完毕,可以绘制以下内容
    
    if (this.drawTable)
    
    {
    
    GUI.Window(0, new Rect(0, 0, 300, 300), (id) =>
    
    {
    
    //第一个文本框用于输入年龄
    
    this.age = GUI.TextField(new Rect(30, 30, 80, 20), this.age);
    
    //第二个文本框用于输入性别
    
    this.gender = GUI.TextField(new Rect(30, 50, 80, 20), this.gender);
    
    //第三个文本框用于输入名字
    
    this.name = GUI.TextField(new Rect(30, 70, 80, 20), this.name);
    
    //点击Insert按钮的Click事件
    
    if (GUI.Button(new Rect(30, 200, 100, 20), "Insert"))
    
    {
    
    //创建一个和tb_Students表结构一样的空实体
    
    var entity = this.context.Tables["tb_Students"].NewEntity();
    
    //给ID字段赋值
    
    entity["ID"] = Guid.NewGuid();
    
    //给StudentName字段赋值
    
    entity["StudentName"] = this.name;
    
    //给Age字段赋值
    
    entity["Age"] = int.Parse(this.age);
    
    //给Gender字段赋值
    
    entity["Gender"] = this.gender == "Male" ? true : false;
    
    //将新建立的实体加入到表中
    
    this.context.Tables["tb_Students"].Add(entity);
    
     
    
    //保存添加操作
    
    this.context.SaveChanges();
    
    }
    
    }, "Insert Test");
    
    }
    
        }
    
    }

     

    修改和删除数据

    修改和删除的步骤基本类似,大体要经过如下几个步骤:

      1. 首先要找到对应的实体,代码如下所示:

        var student=this.context.Tables["tb_Students"].FirstOrDefault(s=>s.StudentName=='user1');

      2. 如果要删除该实体,则调用其Delete方法,代码如下所示:

        if(student!=null)

        {

            student.Delete();

        }

      3. 如果是要修改,则直接修改该实体中对应的属性值,代码如下所示:

        student["Age"]=10;

        student["Gender"]=true;

      4. 保修修改,代码如下所示:

        this.context.SaveChanges();

    完整的修改和删除的代码如下所示:

    using System;
    
    using System.Collections.Generic;
    
    using System.Linq;
    
    using System.Text;
    
    using UnityEngine;
    
    using Warensoft.Unity.Communication.Client.DataClient;
    
    using Warensoft.Unity.Communication.Client;
    
    public class Paging : MonoBehaviour
    
    {
    
    UnityCommunicationManager cm;
    
    DataContext context;
    
    public void Start()
    
    {
    
    cm = UnityCommunicationManager.CreateInstance();
    
    this.context = this.cm.CreateDataContext("http://localhost:20869/Web/Default.aspx");
    
    this.context.Error += new EventHandler<ErrorEventArgs>(this.OnContextError);
    
    this.context.SchemaLoadCompleted += new EventHandler(context_SchemaLoadCompleted);
    
    }
    
     
    
    void context_SchemaLoadCompleted(object sender, EventArgs e)
    
    {
    
    //设置查询条件
    
    var query = new DataQuery();
    
    //加载表中所有记录
    
    this.context.Tables["tb_Students"].LoadAsync(() =>
    
    {
    
    //计算分页数量
    
    this.pageCount = this.context.Tables["tb_Students"].Count / this.pageCapacity;
    
    if (this.context.Tables["tb_Students"].Count%this.pageCapacity!=0)
    
    {
    
    this.pageCount++;
    
    }
    
    //通知OnGUI可以进行显示
    
    this.drawTable = true;
    
    },query.GreaterThanOrEqualsTo("Age",10).Take(50));
    
    }
    
    public void OnContextError(object sender, ErrorEventArgs e)
    
    {
    
    print(e.Message);
    
    }
    
     
    
    private bool drawTable = false;
    
    private int pageNumber = 0;
    
    private int pageCapacity = 5;
    
    private int pageCount = 0;
    
    public void OnGUI()
    
    {
    
    if (this.drawTable)
    
    {
    
    //计算该分页中的数据
    
    var data = this.context.Tables["tb_Students"].Entities.
    
    Skip(this.pageNumber * this.pageCapacity).
    
    Take(this.pageCapacity );
    
    //绘制窗口
    
    GUI.Window(0, new Rect(0, 0, 400, 300), (id) =>
    
    {
    
    int row = 30;
    
     
    
    foreach (var entity in data)
    
    {
    
    //显示第一列,StudentName
    
    GUI.Label(new Rect(10, row, 100, 20), entity["StudentName"].ToString());
    
    //显示第二列,Age,该行代码表示,Age列可以修改
    
    entity["Age"] = int.Parse(GUI.TextField(new Rect(100, row, 100, 20), entity["Age"].ToString()));
    
    //显示第三列,Gender
    
    GUI.Label(new Rect(230, row, 60, 20), entity["Gender"].ToString() == "True" ? "Male" : "Female");
    
    //删除按钮
    
    if (GUI.Button(new Rect(300, row, 100, 20), "Delete"))
    
    {
    
    entity.Delete();
    
    }
    
    row += 50;
    
    }
    
    //上翻页按钮
    
    if (GUI.Button(new Rect(80, 270, 80, 20), "Previous"))
    
    {
    
    if (this.pageNumber > 0)
    
    {
    
    this.pageNumber--;
    
    }
    
     
    
    }
    
    //下翻页按钮
    
    if (GUI.Button(new Rect(180, 270, 80, 20), "Next"))
    
    {
    
    if (this.pageNumber < this.pageCount - 1)
    
    {
    
    this.pageNumber++;
    
     
    
    }
    
     
    
    }
    
    //保存按钮
    
    if (GUI.Button(new Rect(280, 270, 80, 20), "Save"))
    
    {
    
    this.context.SaveChanges(RefreshMode.ClientWins);
    
    }
    
    }, "tb_Students");
    
     
    
    }
    
    }
    
    }

     

  • 相关阅读:
    简单小巧的跨平台共享内存代码
    调试发行版程序 (二)
    休息日公园独步偶得
    Minimum Depth of Binary Tree
    LeetCode Length of Last word
    黑书 折纸痕 uva 177
    Palindrome Partitioning II leetcode
    Acumem ThreadSpotter
    C++ string int 转换 split
    Valid Palindrome Leetcode
  • 原文地址:https://www.cnblogs.com/warensoft/p/2478169.html
Copyright © 2020-2023  润新知