.NET Core MongoDB的简单使用


一、创建测试库、测试表、添加测试数据

使用之前文章提到的MongoDB Compass用法分别添加数据库[myDb]和集合(表)[userinfos]信息,

参考链接为:MongoDB Compass的安装及使用图文说明(非常详细),同时数据库连接语句也可从MongoDB Compass中获得

img

使用mongo shell命令添加测试数据

img

添加完成,MongoDB Compass中可看到已添加的数据

img

二、新建ASP.NET Core Web API项目

1、使用NuGet包管理器添加MongoDB.Driver

img

2、编写demo示例

1)插入

向myDb.userinfos中插入一条数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/// <summary>
/// 插入数据demo(仅可执行一次)
/// </summary>
[HttpGet, HttpPost]
public void InsertDemo()
{
// 连接数据库
var client = new MongoClient("mongodb://localhost:27017/?readPreference=primary&appname=MongoDB%20Compass&ssl=false");
// 获取DataBase
var mydb = client.GetDatabase("myDb");
// 获取Collection
var mycollection = mydb.GetCollection<BsonDocument>("userinfos");
// 待添加的document
// 待添加的document
var doc = new BsonDocument {
{ "_id", 7 },
{ "name", "吴九" },
{ "age", 29 },
{ "ename", new BsonDocument
{
{ "firstname", "jiu" },
{ "lastname", "wu" }
}
}
};
// InsertOne() 添加单条document
mycollection.InsertOne(doc);
// 添加多条document
//mycollection.InsertMany(IEnumerable<BsonDocument> docs);
}

在MongoDB compass中可以看到新增的数据

img

2)查询

① 简单查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/// <summary>
/// 简单查询(Find)
/// </summary>
[HttpGet, HttpPost]
public void SearchByFindOrFilter()
{
// 连接数据库
var client = new MongoClient("mongodb://localhost:27017/?readPreference=primary&appname=MongoDB%20Compass&ssl=false");
// 获取DataBase
var mydb = client.GetDatabase("myDb");
// 获取Collection
var mycollection = mydb.GetCollection<BsonDocument>("userinfos");
// Filter用于过滤,如查询name = '吴九' 的第一条记录
var filter = Builders<BsonDocument>.Filter;
// Find(Filter)进行查询
var doc = mycollection.Find(filter.Eq("name", "吴九")).FirstOrDefault();
Console.WriteLine("简单查询结果:" + doc);
}

简单查询结果为:

img

② AND查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/// <summary>
/// AND查询
/// </summary>
[HttpGet, HttpPost]
public void SearchByAnd()
{
// 连接数据库
var client = new MongoClient("mongodb://localhost:27017/?readPreference=primary&appname=MongoDB%20Compass&ssl=false");
// 获取DataBase
var mydb = client.GetDatabase("myDb");
// 获取Collection
var mycollection = mydb.GetCollection<BsonDocument>("userinfos");
// 查询年龄大于25且小于28的记录
var filter = Builders<BsonDocument>.Filter;
var docs = mycollection.Find(filter.Gt("age", 25) & filter.Lt("age", 28)).ToList();
Console.WriteLine("AND查询结果:" + d)
docs.ForEach(d => Console.WriteLine(d));
}

AND查询结果为:

img

③ OR查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/// <summary>
/// OR查询
/// </summary>
[HttpGet, HttpPost]
public void SearchByOr()
{
// 连接数据库
var client = new MongoClient("mongodb://localhost:27017/?readPreference=primary&appname=MongoDB%20Compass&ssl=false");
// 获取DataBase
var mydb = client.GetDatabase("myDb");
// 获取Collection
var mycollection = mydb.GetCollection<BsonDocument>("userinfos");
// 查询年龄小于25或大于28的记录
var filter = Builders<BsonDocument>.Filter;
var docs = mycollection.Find(filter.Lt("age", 25) | filter.Gt("age", 28)).ToList();
Console.WriteLine("OR查询结果为:");
docs.ForEach(d => Console.WriteLine(d));
}

OR查询结果为:

img

④ 字段存在(Exists)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/// <summary>
/// 字段存在(Exists)
/// </summary>
[HttpGet, HttpPost]
public void SearchIsExists()
{
// 连接数据库
var client = new MongoClient("mongodb://localhost:27017/?readPreference=primary&appname=MongoDB%20Compass&ssl=false");
// 获取DataBase
var mydb = client.GetDatabase("myDb");
// 获取Collection
var mycollection = mydb.GetCollection<BsonDocument>("userinfos");
// 查询存在address字段的记录
var filter = Builders< BsonDocument>.Filter;
var docs = mycollection.Find(filter.Exists("address")).ToList();
Console.WriteLine("存在address记录的查询结果为:");
docs.ForEach(d => Console.WriteLine(d));
}

字段存在(Exists)的查询结果为:

img

⑤ 排序(Sort)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/// <summary>
/// 排序(Sort)
/// </summary>
[HttpGet, HttpPost]
public void SearchWithSort()
{
// 连接数据库
var client = new MongoClient("mongodb://localhost:27017/?readPreference=primary&appname=MongoDB%20Compass&ssl=false");
// 获取DataBase
var mydb = client.GetDatabase("myDb");
// 获取Collection
var mycollection = mydb.GetCollection<BsonDocument>("userinfos");
// 查询age<26的记录,按年龄倒序排列
var filter = Builders <BsonDocument>.Filter;
var sort = Builders <BsonDocument>.Sort;
var docs = mycollection.Find(filter.Lt("age", 26)) // 过滤
.Sort(sort.Descending("age")) // 排序
.ToList();
Console.WriteLine("排序的查询结果为:");
docs.ForEach(d => Console.WriteLine(d));
}

排序(Sort)的查询结果为:

img

⑥ 查询指定字段(Projection)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/// <summary>
/// 查询指定字段(Projection)
/// </summary>
[HttpGet, HttpPost]
public void SearchWithSpecifyField()
{
// 连接数据库
var client = new MongoClient("mongodb://localhost:27017/?readPreference=primary&appname=MongoDB%20Compass&ssl=false");
// 获取DataBase
var mydb = client.GetDatabase("myDb");
// 获取Collection
var mycollection = mydb.GetCollection<BsonDocument>("userinfos");
// 查询age<26的记录,包含name、age,排除 _id
var filter = Builders<BsonDocument>.Filter;
var project = Builders<BsonDocument>.Projection;
var docs = mycollection.Find(filter.Lt("age", 26)) // 过滤
.Project(project.Include("name") // 包含name
.Include("age") // 包含age
.Exclude("_id")) // 包含_id
.ToList();
Console.WriteLine("查询指定字段的查询结果为:");
docs.ForEach(d => Console.WriteLine(d));
}

查询指定字段(Projection)的查询结果为:

img

3)修改

① 修改单条记录(UpdateOne)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/// <summary>
/// 修改单条记录(UpdateOne)
/// </summary>
[HttpGet, HttpPost]
public void UpdateOneRecord()
{
// 连接数据库
var client = new MongoClient("mongodb://localhost:27017/?readPreference=primary&appname=MongoDB%20Compass&ssl=false");
// 获取DataBase
var mydb = client.GetDatabase("myDb");
// 获取Collection
var mycollection = mydb.GetCollection<BsonDocument > ("userinfos");
var filter = Builders<BsonDocument>.Filter;
var update = Builders<BsonDocument>.Update;
var project = Builders<BsonDocument>.Projection;
var docBefore = mycollection.Find(filter.Eq("name", "张三")).Project(project.Include("age").Include("name")).FirstOrDefault();
Console.WriteLine("修改前单条记录的结果为:" + docBefore);
// 将张三的年龄改为18
mycollection.UpdateOne(filter.Eq("name", "张三"), update.Set("age", 18));
// 查询修改后张三的记录
var docAfter = mycollection.Find(filter.Eq("name", "张三")).Project(project.Include("age").Include("name")).FirstOrDefault();
Console.WriteLine("修改后单条记录的结果为:" + docAfter);
}

② 修改多条记录(UpdateMany)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/// <summary>
/// 修改多条记录(UpdateMany)
/// </summary>
[HttpGet, HttpPost]
public void UpdateManyRecord()
{
// 连接数据库
var client = new MongoClient("mongodb://localhost:27017/?readPreference=primary&appname=MongoDB%20Compass&ssl=false");
// 获取DataBase
var mydb = client.GetDatabase("myDb");
// 获取Collection
var mycollection = mydb.GetCollection<BsonDocument>("userinfos");
var filter = Builders<BsonDocument>.Filter;
var update = Builders<BsonDocument>.Update;
var project = Builders<BsonDocument>.Projection;
var docBefore = mycollection.Find(filter.Empty).Project(project.Include("age").Include("name").Include("mark")) // 没有的列不会显示
.ToList();
Console.WriteLine("修改多条记录前的结果为:");
docBefore.ForEach(d => Console.WriteLine(d));
// 将所有年龄小于25的记录标记为young(如果没有mark字段会自动添加)
UpdateResult result = mycollection.UpdateMany(filter.Lt("age", 25), update.Set("mark", "young"));
if(result.IsModifiedCountAvailable) // 获取一个表示修改后的计数是否可用的值
{
Console.WriteLine($ "符合条件的有{result.MatchedCount}条记录,");
Console.WriteLine($ "一共修改了{result.ModifiedCount}条记录。");
// 查询修改后的记录
var docs = mycollection.Find(filter.Empty).Project(project.Include("age").Include("name").Include("mark")).ToList();
Console.WriteLine("修改多条记录后的结果为:");
docs.ForEach(d => Console.WriteLine(d));
}
else
{
Console.WriteLine("无修改操作!");
}
}

修改多条记录(UpdateMany)的结果为:

img

4)删除

① 删除单条记录(DeleteOne)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/// <summary>
/// 删除单条记录(DeleteOne)
/// </summary>
[HttpGet, HttpPost]
public void DeleteOneRecord()
{
// 连接数据库
var client = new MongoClient("mongodb://localhost:27017/?readPreference=primary&appname=MongoDB%20Compass&ssl=false");
// 获取DataBase
var mydb = client.GetDatabase("myDb");
// 获取Collection
var mycollection = mydb.GetCollection<BsonDocument> ("userinfos");
var filter = Builders<BsonDocument>.Filter;
var project = Builders<BsonDocument>.Projection;
var docBefore = mycollection.Find(filter.Empty).Project(project.Include("age").Include("name").Include("mark")).ToList();
Console.WriteLine("删除张三前的记录的结果为:");
docBefore.ForEach(d => Console.WriteLine(d));
// 删除名字为张三的记录
mycollection.DeleteOne(filter.Eq("name", "张三"));
// 查询删除张三后的记录
var docs = mycollection.Find(filter.Empty).Project(project.Include("age").Include("name").Include("max")).ToList();
Console.WriteLine("删除张三后的记录的结果为:");
docs.ForEach(d => Console.WriteLine(d));
}

删除单条记录(DeleteOne)的结果为:

img

② 删除多条记录(DeleteMany)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/// <summary>
/// 删除多条记录(DeleteMany)
/// </summary>
[HttpGet, HttpPost]
public void DeleteManyRecord()
{
// 连接数据库
var client = new MongoClient("mongodb://localhost:27017/?readPreference=primary&appname=MongoDB%20Compass&ssl=false");
// 获取DataBase
var mydb = client.GetDatabase("myDb");
// 获取Collection
var mycollection = mydb.GetCollection<BsonDocument> ("userinfos");
var filter = Builders<BsonDocument>.Filter;
var project = Builders<BsonDocument>.Projection;
var docBefore = mycollection.Find(filter.Empty).Project(project.Include("age").Include("name").Include("mark")).ToList();
Console.WriteLine("删除所有年龄大于25岁的记录前的结果为:");
docBefore.ForEach(d => Console.WriteLine(d));
// 删除所有年龄大于25岁的记录
DeleteResult result = mycollection.DeleteMany(filter.Gt("age", 25));
Console.WriteLine($ "一共删除了{result.DeletedCount}条记录");
// 查询删除所有年龄大于25岁的记录
var docs = mycollection.Find(filter.Empty).Project(project.Include("age").Include("name").Include("max")).ToList();
Console.WriteLine("删除所有年龄大于25岁的记录后的结果为:");
docs.ForEach(d => Console.WriteLine(d));
}

删除多条记录(DeleteMany)的结果为:

img

5)类型映射

① 查询结果映射到实体类示例

mongoDB支持自动映射,直接使用泛型即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/// <summary>
/// 查询结果映射到实体类示例
/// </summary>
[HttpGet, HttpPost]
public void TypeMappingDemo()
{
// 连接数据库
var client = new MongoClient("mongodb://localhost:27017/?readPreference=primary&appname=MongoDB%20Compass&ssl=false");
// 获取DataBase
var mydb = client.GetDatabase("myDb");
// 获取Collection
var mycollection = mydb.GetCollection<Userinfo>("userinfos");
var filter = Builders<Userinfo>.Filter;
var sort = Builders<Userinfo>.Sort;
List<Userinfo> userinfos = mycollection.Find(filter.Lte("age", 25)) // 查询年龄小于等于25岁的记录
.Sort(sort.Descending("age")) // 按年龄进行倒序
.ToList();
// 遍历结果
userinfos.ForEach(u => Console.WriteLine($ "姓名:{u.name},年龄:{u.age},英文名:{u.ename.firstname} {u.ename.lastname}"));
Console.ReadKey();
}

用户信息类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/// <summary>
/// 用户信息类
/// </summary>
public class Userinfo
{
/// <summary>
/// id
/// </summary>
public int _id { get; set; }
/// <summary>
/// 姓名
/// </summary>
public string name { get; set; }
/// <summary>
/// 年龄
/// </summary>
public int age { get; set; }
/// <summary>
/// 等级
/// </summary>
public int level { get; set; }
/// <summary>
/// 英文名
/// </summary>
public Ename ename { get; set; }
/// <summary>
/// 角色
/// </summary>
public string[] roles { get; set; }
/// <summary>
/// 地址
/// </summary>
public string address { get; set; }
/// <summary>
/// 标记
/// </summary>
public string mark { get; set; }
}

英文名类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/// <summary>
/// 英文名
/// </summary>
public class Ename
{
/// <summary>
///
/// </summary>
public string firstname { get; set; }
/// <summary>
///
/// </summary>
public string lastname { get; set; }
}

查询结果映射到实体类示例的结果为:

img

② 查询结果映射到实体类示例 - 常用属性修改上方代码

上边的例子仅仅用了基本的自动化映射,使用基本的自动化映射时:类和Bson中的字段必须严格一致(_id除外,可以自动映射到_id/id/Id),且Bson中的每一个字段在实体类中都必须有一个对应的字段,不然就会抛出异常,这就造成我们可能要写一个非常庞大的实体类,而且类中的字段命名也要严格和Bson中的字段一致。这些限制对我们开发来说是不能接受的,这里我们采用mongoDriver中的一些属性改进一下上边的代码,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/// <summary>
/// 查询结果映射到实体类示例 - 常用属性修改上方代码
/// </summary>
[HttpGet, HttpPost]
public void TypeMappingWithCommonAttributes()
{
// 连接数据库
var client = new MongoClient("mongodb://localhost:27017/?readPreference=primary&appname=MongoDB%20Compass&ssl=false");
// 获取DataBase
var mydb = client.GetDatabase("myDb");
// 获取Collection
var mycollection = mydb.GetCollection<UserinfoBson>("userinfos");
var filter = Builders<UserinfoBson>.Filter;
var sort = Builders<UserinfoBson>.Sort;
List<UserinfoBson> userinfos = mycollection.Find(filter.Lte("age", 25)) // 查询年龄小于等于25岁的记录
.Sort(sort.Descending("age")) // 按年龄进行倒序
.ToList();
// 遍历结果
userinfos.ForEach(u =>
{
Console.WriteLine($ "编号:{u.userId},姓名:{u.name},年龄:{u.age},英文名:{u.ename?.ming} {u.ename.xing},性别:{u.gender}");
Console.WriteLine($ "其他属性:{u.otherprops}");
Console.WriteLine();
});
Console.ReadKey();
}

用户信息类 - Bson

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/// <summary>
/// 用户信息类 - Bson
/// </summary>
public class UserinfoBson
{
/// <summary>
/// id
/// </summary>
[BsonId] // BsonId修饰的字段对应BsonDocument中的_id;
public int userId { get; set; }
/// <summary>
/// 姓名
/// </summary>
public string name { get; set; }
/// <summary>
/// 年龄
/// </summary>
public int age { get; set; }
/// <summary>
/// 英文名
/// </summary>
public EnameBson ename { get; set; }
/// <summary>
/// 性别
/// </summary>
[BsonDefaultValue('男')] // BsonDefaultValue(value)用于指定默认值;
public char gender { get; set; }
/// <summary>
/// 昵称
/// </summary>
[BsonIgnore] // BsonIgnore表示不映射,即使BsonDocument中包含该字段也不会赋值给属性;
public string nickname { get; set; }
/// <summary>
/// 其他属性
/// </summary>
[BsonExtraElements] // BsonExtraElements修饰的字段用于存储没有映射到类中的其他属性;
public BsonDocument otherprops { get; set; }
}

英文名类 - Bson

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/// <summary>
/// 英文名 - Bson
/// </summary>
public class EnameBson
{
/// <summary>
///
/// </summary>
[BsonElement("firstname")] // BsonElement可以指定修饰的属性映射到BsonDocument中的哪个字段
public string ming { get; set; }
/// <summary>
///
/// </summary>
[BsonElement("lastname")]
public string xing { get; set; }
}

查询结果映射到实体类示例 - 常用属性修改上方代码的结果为:

img

6)使用LINQ查询

① 基本查询:查找年龄大于22岁的学生;② 连接查询:查询各个学生的学号、姓名、班级名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/// <summary>
/// 使用LINQ查询
/// </summary>
[HttpGet, HttpPost]
public void LINQQuery()
{
// 连接数据库
var client = new MongoClient("mongodb://localhost:27017/?readPreference=primary&appname=MongoDB%20Compass&ssl=false");
// 获取DataBase
var mydb = client.GetDatabase("myDb");
// 获取Collection
var stuCollection = mydb.GetCollection<Student> ("students");
var clsCollection = mydb.GetCollection <Classx> ("classes");
//查找年龄大于22的学生
Console.WriteLine("-------------查找年龄大于22的学生列表--------------");
//1.query语法
List<Student> stuList1 = (from stu in stuCollection.AsQueryable() where stu.age > 22 select stu).ToList();
//2.点语法
List<Student> stuList2 = stuCollection.AsQueryable().Where(s => s.age > 22).ToList();
stuList1.ForEach(stu => Console.WriteLine($ "姓名:{stu?.stuName}, 年龄:{stu?.age}"));
Console.WriteLine();
//表连接查询,查询各个学生的班级名
Console.WriteLine("-------------表连接,查询学生的班级名----------------");
//1.query语法
var result1 = from stu in stuCollection.AsQueryable()
join cls in clsCollection.AsQueryable()
on stu.classNo equals cls.no
select new
{
stuno = stu.no, stu.stuName, cls.clsName
};
//2.点语法
var result2 = stuCollection.AsQueryable().Join(clsCollection.AsQueryable(), stu => stu.classNo, cls => cls.no, (stu, cls) => new
{
stuno = stu.no, stu.stuName, cls.clsName
});
//遍历结果
foreach(var item in result1)
{
Console.WriteLine($ "学号:{item.stuno}, 姓名:{item.stuName}, 班级:{item.clsName}");
}
Console.ReadKey();
}

学生类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/// <summary>
/// 学生类
/// </summary>
public class Student
{
/// <summary>
/// 学号
/// </summary>
public int no
{ get; set; }
/// <summary>
/// 姓名
/// </summary>
public string stuName
{ get; set; }
/// <summary>
/// 年龄
/// </summary>
public int age { get; set; }
/// <summary>
/// 班级编号
/// </summary>
public int classNo { get; set; }
/// <summary>
/// 其他
/// </summary>
[BsonExtraElements]
public BsonDocument others { get; set; }
}

班级类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/// <summary>
/// 班级类
/// </summary>
public class Classx
{
/// <summary>
/// 班级编号
/// </summary>
public int no { get; set; }
/// <summary>
/// 班级名
/// </summary>
public string clsName { get; set; }
/// <summary>
/// 其他
/// </summary>
[BsonExtraElements]
public BsonDocument others { get; set; }
}

查找年龄大于22岁的学生以及查询各个学生的学号、姓名、班级名的结果如下:

img

三、附录

1、userinfos表测试数据

1
2
3
4
5
6
7
8
9
use myDb
db.userinfos.insertMany([
{_id:1, name: "张三", age: 23,level:10, ename: { firstname: "san", lastname: "zhang"}, roles: ["vip","gen" ]},
{_id:2, name: "李四", age: 24,level:20, ename: { firstname: "si", lastname: "li"}, roles:[ "vip" ]},
{_id:3, name: "王五", age: 25,level:30, ename: { firstname: "wu", lastname: "wang"}, roles: ["gen","vip" ]},
{_id:4, name: "赵六", age: 26,level:40, ename: { firstname: "liu", lastname: "zhao"}, roles: ["gen"] },
{_id:5, name: "田七", age: 27, ename: { firstname: "qi", lastname: "tian"}, address:'北京' },
{_id:6, name: "周八", age: 28,roles:["gen"], address:'上海' }
])

2、student表测试数据

1
2
3
4
5
6
db.students.insertMany([
{"no":1, "stuName":"jack", "age":23, "classNo":1},
{"no":2, "stuName":"tom", "age":20, "classNo":2},
{"no":3, "stuName":"hanmeimei", "age":22, "classNo":1},
{"no":4, "stuName":"lilei", "age":24, "classNo":2}
])

3、classs表测试数据

1
2
3
4
db.classes.insertMany([
{"no" : 1,"clsName" : "A班"},
{"no" : 2,"clsName" : "B班"}
])

4、 MongoDB .NET Driver官方文档:http://mongodb.github.io/mongo-csharp-driver/

以上就是.NET Core MongoDB的简单使用的介绍,做此记录,如有帮助,欢迎点赞关注收藏!


文章作者: GoodTimeGGB
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 GoodTimeGGB !
评论
  目录