C# uses custom classes + dictionary + JSON to fill data, separate from the real database, and implement simple additions, deletions, modifications, and local storage and reading of data.

Preface

This article will not use a database, but will find another way to achieve local storage and reading, addition, deletion, modification and query! ~

The idea I used when writing a project before was that because it was a very small project, I didn’t want to rely on the database for additions, deletions, modifications, and searches, so as to avoid complex database environment support and installation. Before, I wanted to go online to find out if there was an alternative method, but now almost all online databases are used to populate the data. There is no way to use a database. I had no choice but to write it myself!

Before I begin, let me explain the situations in which this article is appropriate:

①Suitable for projects with few data tables.

②Suitable for projects that store data locally.

③Suitable for projects that do not want to rely on a complex database environment, but also want to have the functions of storing, adding, deleting, modifying and querying data.

④ Not elegant or smart, but very simple and crude and can be implemented quickly


Ideas for realizing basic functions

The implementation idea is very simple:

Dictionary: as the main data carrier. Additions, deletions, modifications and checks are made on this basis.

Custom class: as a data table. The creation of the dictionary depends on it.

JSON: used for data storage and reading.

The data table in the database is actually a large key-to-value store , with a primary key corresponding to a column of data.

Dictionary's key pairs perfectly fit our needs.

In C#, the main purpose of Dictionary is to provide fast key-value based element lookup. The structure of a Dictionary is generally like this: Dictionary<[key], [value]>

Description of Dictionary
1. Mapping from a set of keys (Key) to a set of values ​​(Value). Each added item consists of a value and Its associated keys are composed of
2. Any key must be unique.
3. The key cannot be an empty reference null (Nothing in VB). If the value is a reference type, it can be a null value.
4. Key and Value can be of any type. (string, int, custom class, etc.)

①We only need to customize a class first.

public class Client//根据自己需要定义类
{
    public string id;//我们的主键
    public string name;
    public string type;
    public string state;
}

②We define another Dictionary. The Key type of Dictionary is the type of our primary key, and the Value content is our custom class.

public static Dictionary<string,Client> db=new Dictionary<string,Client>();

③Write a method to fill data into the control. Here we take winform's datagridview filling as an example.

Note: The number of Columns in the datagridview must be consistent with the number of fields in your custom class.

public void DataBind()//填充最新的数据,也可以当做刷新的方法
{
    dataGridView1.Rows.Clear();//清空
    //遍历字典的每一个元素
    foreach (var pair in db)
    {
        //此时RowCount-1的大于字典的Count或者字典内没有数据则可以停止填充
        if (dataGridView1.RowCount - 1 > db.Count||db.Count==0) return;
        //新增行
        int index = dataGridView1.Rows.Add();
        //拿到类数据
        var results = db[pair.Key];
        dataGridView1.Rows[index].Cells[0].Value = results.id;
        dataGridView1.Rows[index].Cells[1].Value = results.name;
        dataGridView1.Rows[index].Cells[2].Value = results.type;
        dataGridView1.Rows[index].Cells[3].Value = results.state;
    }
}

④We may need to call this method in many places. If it will cross threads, please rewrite it into Invoke form.

public void DataBind()//填充最新的数据,也可以当做刷新的方法
{
    if (dataGridView1.InvokeRequired)//跨线程
    {
        //委托
        dataGridView1.Invoke(new EventHandler(delegate
        {
            dataGridView1.Rows.Clear();
            foreach (var pair in db)
            {
                //此时RowCount-1的大于字典的Count或者字典内没有数据则可以停止填充
                if (dataGridView1.RowCount - 1 > db.Count||db.Count==0) return;
                //新增行
                int index = dataGridView1.Rows.Add();
                //拿到类数据
                var results = db[pair.Key];
                dataGridView1.Rows[index].Cells[0].Value = results.id;
                dataGridView1.Rows[index].Cells[1].Value = results.name;
                dataGridView1.Rows[index].Cells[2].Value = results.type;
                dataGridView1.Rows[index].Cells[3].Value = results.state;
            }
        }));
    }
    else//没有跨线程
    {
        dataGridView1.Rows.Clear();
        foreach (var pair in db)
        {
            //此时RowCount-1的大于字典的Count或者字典内没有数据则可以停止填充
            if (dataGridView1.RowCount - 1 > db.Count||db.Count==0) return;
            //新增行
            int index = dataGridView1.Rows.Add();
            //拿到类数据
            var results = db[pair.Key];
            dataGridView1.Rows[index].Cells[0].Value = results.id;
            dataGridView1.Rows[index].Cells[1].Value = results.name;
            dataGridView1.Rows[index].Cells[2].Value = results.type;
            dataGridView1.Rows[index].Cells[3].Value = results.state;
        }
    }
}

We can call it in many places. To add, delete or modify a piece of data, we need to call this method to refresh the datagridview immediately. The next step is to implement the method of adding, deleting, modifying and checking.

increase

The method of adding is very simple. First, New our custom class is stored in a variable, fill in the data into the corresponding field under the variable, then insert it into the dictionary, and finally refresh it.

public void Add()
{
    Client p = new Client
    {
        id = Textbox1.Text,
        name = Textbox2.Text,
        type = Textbox3.Text,
        state = Textbox4.Text
    };
    //先查看有没有重复数据插入
    if(!db.ContainsKey(p.id))
    {
        db.Add(p.id, p);//以id为Key,Dictionary的Key唯一,插入数据
    }
    //重复主键则不能插入
    else
    {
        MessageBox.Show("已存在此数据!请勿重复插入!");
        return;
    }
    DataBind();//调用刷新方法,刷新最新数据
}

Demonstration Demo-increased implementation renderings

delete

Deletion is mainly to obtain the primary key. Once the primary key is obtained, the data corresponding to the dictionary can be deleted. Taking datagridview as an example, you need to obtain the index of the row clicked by the user to obtain the incremental data of that row.

public void Del()
{
    int index = dataGridView1.CurrentRow == null ? -1 : dataGridView1.CurrentRow.Index;//获得当前行
    if (index < 0) return;//如果没点击则返回,防止用户没有选中点击也会执行接下来的代码。
    if (dataGridView1.Rows[index].Cells[1].Value == null) return;//选中行没有数据也返回
    string id = dataGridView1.Rows[index].Cells["Id"].Value.ToString().Trim();//获得当前行的id
    if (db.ContainsKey(id))//字典中有才能删,防止意外情况
    {
        db.Remove(id);//删除字典中的对应值
    }
    DataBind();//调用刷新方法,刷新最新数据
}

Demonstration Demo-delete implementation renderings

change

The main thing is to get the information by getting the primary key, transfer the data to the location you want, modify it and save it to the original corresponding key. Note that if a new window is passed in, it must be passed into the new window together with the data and the main window to facilitate calling the refresh code.

public void UpDate()//改
{
    int index = dataGridView1.CurrentRow == null ? -1 : dataGridView1.CurrentRow.Index;//获得当前行
    if (index < 0) return;//如果没点击则返回,防止用户没有选中点击也会执行接下来的代码。
    if (dataGridView1.Rows[index].Cells[1].Value == null) return;//选中行没有数据也返回
    string id = dataGridView1.Rows[index].Cells["Id"].Value.ToString().Trim();//获得当前行的id
    Client res = new Client();
    if (db.ContainsKey(id))//字典中有才能查和删,防止意外情况
    {
        res = db[id];//获取到对应的数据类
    }
    UpDateForm form=new UpDateForm(res,this);//将数据和主窗口传入新的窗口中
    form.Show();//打开新窗口
}
//改的窗口构造函数代码
Mainform form;//创建主窗口变量
Client res;//创建类实例
public UpDateForm(Client digtal,Mainform mainform)
{
    InitializeComponent();
    res=digtal;//数据传入
    form=mainform;//窗口传入

}
//改窗口保存按钮代码
public void UpDateSave()
{
    //注意主键不能修改
    res.name = Textbox2.Text;
    res.type = Textbox3.Text;
    res.state = Textbox4.Text;
    //覆盖原来的内容
    Mainform.db[res.id]=res;
    form.DataBind();//调用主窗口刷新方法,刷新最新数据
    Close();//修改完关闭窗口
}

Demonstration Demo-changed implementation renderings

check

Obtain the primary key, traverse the dictionary and the corresponding content you want to look up, and change the display table according to the conditions that need to be filtered. Similar to DataBind.

Take checking name as an example.

public void Find()
{
    string nameText=TextBox1.Text;//获取name值
    dataGridView1.Rows.Clear();
    //遍历数据库
    foreach (var pair in db)
    {
        if (pair.Value.name == nameText)
        {
            //此时RowCount-1的大于字典的Count或者字典内没有数据则可以停止填充
            if (dataGridView1.RowCount - 1 > db.Count||db.Count==0) return;
            //新增行
            int index = dataGridView1.Rows.Add();
            //拿到类数据
            var results = db[pair.Key];
            dataGridView1.Rows[index].Cells[0].Value = results.id;
            dataGridView1.Rows[index].Cells[1].Value = results.name;
            dataGridView1.Rows[index].Cells[2].Value = results.type;
            dataGridView1.Rows[index].Cells[3].Value = results.state;
        }
    }
    if(dataGridView1.RowCount-1==0)
    {
        DataBind();//没有数据就刷新全部
        MessageBox.Show("没有此数据!");
    }
}

Demonstration Demo-Cha's implementation renderings

The above can basically meet the needs of replacing the data table, but it always exists in the program, disappears when it is closed, and will be blank when it is opened, so our next step is to save the data and open the program next time The corresponding data is read at the same time and stored and read locally.


Implementation of local storage and reading

The inspiration here comes from the archiving method of "The Legend of Knights" . When I couldn't pass the level and wanted to modify the archive, I found that his archive file was a txt file filled with dense JSON statements.

I instantly realized that every time the archive is read, JSON is converted into entity data. To store the archive, the entity data is converted into JSON and written into txt.

虽然不优雅且粗暴,但是很好用。

这里需要引入一个DLL。

using Newtonsoft.Json;//用于将实体类转为json语句,或者将json语句转为实体类

本地存储

每次存储的时候都是在退出的时候再做存储(如果你想在录入新数据的时候存储,也可以自己改)。

原理也很简单,我们用一个json类,每次退出前,先将目前的字典,一个个输出为一条条json语句,存储起来在本地的某个txt中即可。

将方法写入窗口的Closing方法中。

string path = Application.StartupPath;//获取程序路径
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)//关闭窗体
{

    DialogResult diRes = MessageBox.Show("是否关闭程序?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
    if (diRes == DialogResult.OK)
    {
        if (!File.Exists($"{path}/config/MainSet.txt"))//如果是第一次创建
        {
            StreamWriter sw = new StreamWriter($"{path}/config/MainSet.txt", false);//写入文件,覆盖模式
            //遍历字典
            foreach (var item in db)
            {
                //将实体类转为字符串
                string jsonStr = JsonConvert.SerializeObject(item.Value);
                //写入txt
                sw.WriteLine(jsonStr);
            }
            //关闭
            sw.Close();

        }
        else//改写习惯
        {
            string all = "";
            if (db.Count > 0)
            {    //遍历字典
                foreach (var item in db)
                {
                    string jsonStr = JsonConvert.SerializeObject(item.Value);
                    all += jsonStr + "\n";
                }
            }
            File.WriteAllText($"{path}/config/MainSet.txt", all);
        }
    }
    else//假如用户取消了退出
    {
        e.Cancel = true;//取消退出
        return;//结束方法
    }

}

本地读取

每次读取是在程序打开的时候。我们从我们存储的txt文件中读取所有的JSON语句并转化成实体类存入字典中,并刷新填充datagridview。

将方法写入窗口的Load方法中。

string path = Application.StartupPath;//获取程序路径
private void MainForm_Load(object sender, EventArgs e)
{
    if (File.Exists($"{path}/config/MainSet.txt"))//查找这个文件是否存在
    {
        string[] lines = File.ReadAllLines($"{path}/config/MainSet.txt");//一行行写入一个字符串数组
        for (int i = 0; i < lines.Length; i++)
        {
            Client a = JsonConvert.DeserializeObject<Client>(lines[i]);//每一句都解析成类保存
            string Id = a.id;
            if (!db.ContainsKey(Id))
            {
                db.Add(Id, a);
            }
        }
    }
    DataBind();//填充列表
}

本地存储与读取效果图,成功保留表数据

JSON的txt文件展示,数据就是以这种形式保存下来的(跟侠客风云传前传的存档文件一毛一样,有兴趣的可以去看看)。

结语

好了!到这里已经全部结束了,还望大家多多指教,能帮到大家那是最好的!

你已经是一个脱离数据库的特殊crud选手了!!快来做一个多线程Socket连接程序吧!(不是)

这是博主的项目(- ▽ -)给你们露两手!

Guess you like

Origin blog.csdn.net/aa989111337/article/details/128643602