MongoDB 是一个基于分布式文件存储的数据库,被称之为最像关系数据库的NoSQL,因其适于存储海量数据的特点,近年来,广泛被应用于Web及大数据等领域。
在此,对笔者学习MongoDB时所遇到的问题进行记录。
在Mongodb安装过程中,遇到了安装报错,弹出消息框,如图示:
翻译报错内容为:服务“MongoDB服务器(MongoDB)”(MongoDB)无法启动。请验证您是否有足够的权限启动系统服务。
此时,打开系统服务启动界面,尝试启动MongoDB Server服务程序,发现程序无法手动启动
查阅网络资料:(21条消息) MongoDB安装坑:弹出的提示框提示服务显示mongodb服务未启动_Hkz74的博客-CSDN博客 得以解决。
在MongoDB程序启动时,出现闪退。
查阅资料,发现该问题为缺少MongoDB数据存储路径产生的,解决方法:
在MongoDB所在盘下的根目录创建一个data文件夹,并在data文件夹里创建一个db文件夹
例如,MongoDB在C盘的一个文件中,就在C盘根目录下创建data,然后打开cmd,进入MongoDB的bin目录下,输入mongod --dbpath c:/data,重新启动MongoDB程序,即可正常使用。
在对MongoDB使用过程中出现的问题尝试进行解决时,常出现运用多种方法解决未果的情况,此时,尝试对MongoDB进行卸载重装,在对MongoDB进行卸载时,需要注意以下问题:
因在程序安装过程中,生成了当前程序的系统服务,所以,彻底卸载mongodb前需要先手动对MongoDB服务程序进行删除,否则,在重装mongodb会产生服务冲突
首先,以管理员身份打开CMD命令窗口 输入 net stop mongodb停止服务
接着对服务进行删除 输入 sc delete MongoDB 注意:这里的MongoDB需要跟系统服务中的mongodb,服务名称大小写一致
对服务进行删除后,便可执行对MongoDB的删除操作 mongod --remove
对于MongoDB数据库的学习,只学习其本身的数据库知识是不够的,学习数据库,要基于项目开发之上,才更能深刻理解其理论,掌握其实际操作技能,在学习MongoDB过程中,基于笔者技术栈,选择以C#为主体开发语言,Winforms为开发框架,结合MongoDB数据库,目标完成一个电子病历系统开发,在以下内容中,将会以开发该电子病历系统为核心,对开发过程中所遇到的问题进行记录。
要在VS开发环境中对MongoDB数据库进行操作,首先需要安装MongoDB相关的NuGet包
开发一个系统,首个页面毋庸置疑是登录模块,即是对现有用户的账号与密码进行验证,但是这里要注意的是,NoSQL与关系型数据库不同,因其具备的高度可扩展性,所以没有关系型数据库那样固定的一个表结构,通俗地讲,其列是不固定的,这就导致了,在C#中对MongoDB集合中特定文档内容的提取难以像关系型数据库在表中对记录进行操作那样方便。
于是,在编写登录功能时,起初采用了如下方式对用户的账号密码进行验证
//var NoFilterDic = new Dictionary<string, string> { { $"DocNo", $"{this.txb_userId.Text.Trim()}" } };
//var Nofilter = new BsonDocument(NoFilterDic);
//var Notrue = collection.Find(Nofilter).Any();
//var PassFilterDic = new Dictionary<string, string> { { $"Password", $"{this.txb_userpassword.Text.Trim()}" } };
//var Passfilter = new BsonDocument(PassFilterDic);
//var Passtrue = collection.Find(Passfilter).Any();
//if (Notrue)
//{
// if (Passtrue)
// {
// frm_HomePage frm_HomePage = new frm_HomePage();
// this.Hide();
// frm_HomePage.ShowDialog();
// this.Dispose();
// this.Close();
// }
// else
// {
// MessageBox.Show("密码错误");
// return;
// }
//}
//else
//{
// MessageBox.Show("账号错误");
// return;
//}
其思路是判断指定集合中文档是否存在,并通过bool值进行验证,但这样的方法虽然可以实现登录,毫无疑问会出现问题,举例:若在账号文本框中输入甲用户的账号,在密码文本框中输入乙用户的密码,因这两条记录都存在于该集合当中,因此两个bool值都返回true,实现了if语句中的代码,但这样并不是正确的验证方式。
正确操作应当如下:
string doc_no = this.txb_userId.Text.Trim();
string password = this.txb_userpassword.Text;
var result = collection.Find(n => n.DocNo == doc_no && n.Password == password).Any();
if (result)
{
frm_HomePage frm_HomePage = new frm_HomePage();
this.Hide();
frm_HomePage.ShowDialog();
this.Dispose();
this.Close();
}
else
{
MessageBox.Show("账号或密码错误");
}
使用lambda表达式,判断是否存在同时拥有符合条件的账号密码的集合,来达到验证指定用户的目的。
在对winform窗体进行开发过程中,出现了窗体设计器错误页的提示,“菜单命令“5efc7975-14bc-11cf-9b2b-00aa00573819 : 17”已经有一个命令处理程序。”,导致窗体设计器无法正常显示,在代码中未提示报错,尝试重启项目得以解决。
微软官方帮助:
NoSql Manager:
为对MongoDB数据库进行更方便的操作,下载了NoSQL Manager可视化工具
但其为试用版
查得如下方法可解除试用限制:
运行 -->regedit
HKEY_CURRENT_USER\Software\NoSQL Manager Group
删除该文件夹
C:\ProgramData\NoSQL Manager Group
NoSQL Manager for Mongo
重启,即可继续免费试用15天
在借助NoSQL Manager对数据库进行操作时,发现无法在shell窗口中输入中文
打开设置窗口并勾选Support hieroglyphs即可输入并显示中文
DocumentView初始显示视图默认以TreeView出现,在查询后并不方便查看数据内容
可在选项中的DataView将默认视图模板进行修改
DevExpress:
在使用MongoDB+c#对医疗系统进行开发时,探索并使用了.NET平台的DevExpress开发框架,DevExpress强大的功能能够帮助我们快速进行前端页面的开发,并且能实现许多原生Winform难以实现的强大业务功能,如XtraReport能帮助我们制作报表,在医疗系统中即可帮助我们实现病历的模板化,还有如ChartControl可以帮助我们实现一些医疗数据的可视化等等。
但是其能实现各种各样更强大功能的同时也意味着其开发难度随之上升,对开发者的编程能力无疑带来了更大的挑战。
在笔者使用DevExpress框架进行系统开发之时,也毋庸置疑的遇到了许多问题,在此记录。
在笔者使用ReportControls模块进行病历的电子模板化时,希望做出一个可编辑内容的病历报表,但是在各控件的使用过程中,控件一开始都处于不可编辑的状态。
查询资料并查阅文档未得到解决办法,并自行在控件的属性界面下寻找解决方法,一般这种功能都是通过属性来进行控制。
果然,其编辑属性EditOptions藏匿于各个单独的报表控件之下,需要逐一对打算开启编辑功能的报表控件进行点击,进入其EditOptions菜单栏下,将Enabled属性更改为True后,即可启用报表控件的编辑功能。
DevExpress的gridControl控件非常强大,其可以看作由Winform的GridView衍生而来,但是其不仅在GridView上增加了许多新的功能,还提供了多种视图样式,如CardView、BandGridView、TileView等等,每种视图都能以不同的界面呈现出后端数据,使我们在呈现表格数据时有了更多更精美的页面样式。
对于gridview这样的控件,我们比较常用的一个操作便是获取选中单元格中的值,但是,在DevExpress的gridControl中我们要进行这个操作则不像在winform中那么简单直接,这也是笔者刚接触这个控件时比较头疼的一个地方。
例如,在winform中,我们要读取指定的gridview的单元格内容,我们只需要从gridview的属性当中检索。如
//取单元格数据三种方法
this.dataGridView1[e.ColumnIndex, e.RowIndex].Value.ToString();//第一种取法
this.dataGridView1.Rows[e.RowIndex].Cells["你所要取值的列名称"].Value.ToString();//第二种取法
this.dataGridView1.CurrentRow.Cells["你所要取值的列名称"].Value.ToString();//第三种取法
但是,在devexpress中,虽然我们一开始拖入的控件是gridcontrol,但是我们呈现的数据却是在这个gridcontrol下的各个view里面,也就是说,这个数据网格控件gridcontrol不仅仅只能呈现一个视图,其甚至可以有view2、view3...
所以,当我们要获取指定单元格的数据时,即需要从指定的view当中获取。
以下是一个示例代码:
string cellValue = null;
int rowIndex = layoutView1.FocusedRowHandle; // 获取焦点行的索引
int columnIndex = layoutView1.Columns["ColumnName"].VisibleIndex; // 获取指定列的索引
if (rowIndex >= 0 && columnIndex >= 0)
{
cellValue = layoutView1.GetCellValue(rowIndex, columnIndex) as string; // 获取字符串值
}
在笔者系统开发过程中,结合MongoDB以Bson文档格式进行存储的特性,想到其内嵌文档的格式非常类似于树形结构,即可用其来生成TreeList的结点。
于是笔者探寻了在C#中使用Json内嵌文档生成Devexpress的treeList控件结点的方法。
// 创建一个JSON字符串
string json = @"[
{
'id': 1,
'text': '中医科',
'nodes': [
{
'id': 2,
'text': '当前患者'
/*,'nodes': [
{
'id': 6,
'text': '内嵌文档'
},
{
'id': 7,
'text': '生成树节点'
}
]*/
},
{
'id': 3,
'text': '出院患者'
}
]
},
{
'id': 4,
'text': '骨科'
},
{
'id': 5,
'text': '血液科'
}
]";
// 将JSON字符串转换为JArray对象
JArray jsonArray = JArray.Parse(json);
// 遍历JArray对象,向TreeList添加节点
foreach (JObject obj in jsonArray.Children<JObject>())
{
TreeListNode node = treeList_dep.AppendNode(new object[] { obj["text"].ToString() }, null);
node.Tag = obj["id"].ToString();
if (obj["nodes"] != null)
{
AddNodes(node, obj["nodes"].ToString());
}
}
// treeList递归添加子节点
private void AddNodes(TreeListNode parentNode, string json)
{
JArray jsonArray = JArray.Parse(json);
foreach (JObject obj in jsonArray.Children<JObject>())
{
TreeListNode node = treeList_dep.AppendNode(new object[] { obj["text"].ToString() }, parentNode);
node.Tag = obj["id"].ToString();
if (obj["nodes"] != null)
{
AddNodes(node, obj["nodes"].ToString());
}
}
}
使用以上代码便可将json字符串转化为TreeList结点,当然,Winform的TreeView控件同理,我们也可通过将json文档对象添加进MongoDB数据库中,在程序中根据内嵌文档创建对应的对象类,通过读取MongoDB数据库内容来生成对应的树节点。
在项目学习过程中,从MongoDB到c#,再到Devexpress,所遇问题甚多,有些问题可能因为多种原因,忘记记录,实在可惜,后续若有遇到,将再行补充,学习的内容,不局限于数据库,还涉及软件、编程语言、开发框架、业务知识等等多个层面,可以说,完成一个综合项目的任务,对于学习人员综合能力的快速提升能起到非常大的帮助,项目中一个业务问题的解决,可能就需要我们获取一些新的知识,或是深入技术研究,这便巩固加深了学者的专业技术能力,扩展了技术栈,笔者从中受益良多。
MongoDB初步学习阶段,仍需历练,积累错误,方能成长,欢迎大家共同探讨,一同进步。