SqlSugar中的MongoDB使用

简介

在SqlSugar官方文档中是这么介绍的:

SqlSugar 拥有最强的 MongoDB 的功能支持,表达式解析是目前所有 ORM 最强的。

首先使用 NUGET 安装以下两个包(推荐直接安装最新的,功能支持比较全):

dotnet add package SqlSugar.MongoDbCore
dotnet add package SqlSugarCore

支持的功能:单表CRUD、简单联表 、分页、排序、简单分组、嵌套文件(类JSON类型)、非对象方式更新、非对象方式删除、事务、插入或者更新。

不支持功能:子查询和导航查询。

参考链接: 数据库操作中的子查询和导航查询

官方文档:

.NET中使用 MongoDB 数据库 - SqlSugar 5x - .NET果糖网

配置依赖

在创建 HostBuilder 之前(推荐该方式,在 Program.cs 中):

using SqlSugar.MongoDb;

// 注册自定义程序集
InstanceFactory.CustomAssemblies = new System.Reflection.Assembly[] {
    typeof(MongoDbProvider).Assembly
};

var builder = WebApplication.CreateBuilder(args);
// 其他配置...

数据库连接

创建 Db 对象:

// db对象(用法和 SqlSugar 入门中一样)
var Db = new SqlSugarClient(new ConnectionConfig()
{
    IsAutoCloseConnection = true,
    DbType = DbType.MongoDb,
    ConnectionString = SqlSugarConnectionString 
},
it =>
{ 
    it.Aop.OnLogExecuting = (sql, para) =>
    {
        Console.WriteLine(UtilMethods.GetNativeSql(sql, para));
    };
});
 
// 字符串 2 种都可以
var ConnectionString = "mongodb://root:[email protected]:27017/testDB?authSource=admin";
var ConnectionString = "host=222.71.212.3;Port=27017;Database=testDB;Username= root;Password=123456;authSource=admin;replicaSet=";

实体类定义

主键定义:继承 MongoDbBase 里面自定义好了主键。

外键定义:设置 ColumnDataType = nameof(ObjectId)

创建一个实体类(以 Student)为例:

// 继承的 MongoDbBase 里面已经有了主键,当然也可以复制出来不用基类
public class Student : MongoDbBase
{
    // 主键在基类,也可以自己复制出来不用基类
    public string Name { get; set; }

    // 外键需要设置 ObjectId 类型不然存储会的是 string
    [SqlSugar.SugarColumn(ColumnDataType = nameof(ObjectId))]
    public string SchoolId { get; set; }
}

// MongoDbBase 是 ORM 自带的一个基类,方便使用时不定义主键
public class MongoDbBase
{
    [SugarColumn(IsPrimaryKey = true, IsOnlyIgnoreInsert = true, ColumnName = "_id")]
    public string Id { get; set; }
}

其他三个常用特性:

// 常用特性说明
[SugarColumn(IsIgnore = true)] // 忽略这列不处理
[SugarColumn(ColumnName ="Name")] // 属性名和列名不一样可以设置列名
[SugarColumn(IsJson= true)] // 标识是否为子对象

CURD示例

插入

// 无返回值插入
db.Insertable(data).ExecuteCommand();
 
// 插入并将主键赋值到实体
db.Insertable(data).ExecuteCommandIdentityIntoEntity();
 
// 插入返回 IDS
var ids = db.Insertable(data).ExecuteReturnPkList<string>();

查询

MongoDB 一般是单表操作比较多,官方并不推荐联表操作,一般用JSON做嵌套文档比较多,不过SqlSugar也支持了联表:

不过可以通过聚合根或管道来实现C#原生的MongoDB多表联查。

// 简单查询
var data2 = db.Queryable<Student>().Where(it => it.Num == 1).ToList(); 

// 分页
var count = 0;
var list = db.Queryable<School>().OrderBy(it => it.Name).ToPageList(1, 2, ref count); 

// JSON类型(实体定义 isJson)
var data2 = db.Queryable<Student>().Where(it => it.Book.Price == 1).ToList();

// 简单联表(目前只能支持这种基本联表)
var list = db.Queryable<Student>()
    .LeftJoin<School>((x, y) => x.SchoolId == y.Id)
    .LeftJoin<School>((x, y, z) => x.SchoolId == z.Id)
    .Where((x, y) =>y.Name == "TestSchool")
    .Select((x, y,z) => new
    {
        StudentName = x.Name,
        SchoolName = y.Name,
        SchoolName2 = z.Name
    }).ToList();

// 简单分组查询
var list14 = db.Queryable<OrderInfo>()
    .GroupBy(it => new { it.Name, it.Price })
    .Select(it => new
    {
        key = it.Name,
        Prie = it.Price,
        groupCount = SqlFunc.AggregateCount(it.Id),
        max = SqlFunc.AggregateMax(it.Id),
        min = SqlFunc.AggregateMin(it.Id)
    }).ToList(); 

删除

// 根据主键删除
string [] ids= [...]
db.Deleteable<Student>().In(ids).ExecuteCommandAsync()
 
// 根据实体删除,实体要有主键 
var delrow = db.Deleteable(data).ExecuteCommand();

更新

var updateRow2 = db.Updateable(new List<OrderInfo>() 
    {
        new OrderInfo() { Id = ids.First(),Name="a31",Price=11},
        new OrderInfo() { Id = ids.Last(),Name="a41"}
    })
    .ExecuteCommand();

var updateRow3= db.Updateable<OrderInfo>()
    .SetColumns(it=>it.Name=="xx")
    .Where(it=> it.Id == id)
    .ExecuteCommand();

原生SQL语句

参数说明:


// 参数必须是一个完整的对象
db.表名.update({ "filter" : {...}, "update" : { "$set" : {.. } }) // 其中参数是一个标准的对象

// 错误写法
db.表名.update( para1, para2) // 把 filter 和 update 去掉了变成了 2 个参数,这种 ORM 不支持,ORM 只能解析一个参数重载

示例:

db.Ado.ExecuteCommand(@"db.table100.insertMany([{ ""Name"" : ""XX大学"" }])");

// C# 对象构造
var documents = new[]
{
    new BsonDocument { { "Name", "XX大学" } }
};
var json = new BsonArray(documents).ToJson();
var cmd = $"db.table100.insertMany({json})";
db.Ado.ExecuteCommand(cmd);

// 查询
 var list = db.Ado.SqlQuery<T>(cmd);
 var dt = db.Ado.GetDataTable(cmd); 
// 写入操作
 db.Ado.ExecuteCommand(cmd);
  
// SqlSugar 中获取原生对象
IMongoDatabase rdb= ((MongoDbConnection)db.Ado.Connection).GetDatabase();

// IMongoDatabase 实现(仓储层)
// var client = new MongoClient("mongodb://localhost:27017");
// IMongoDatabase database = client.GetDatabase("TestDatabase");

主键用法

// ORM 自带的基类
public class MongoDbBase
{
    [BsonRepresentation(BsonType.ObjectId)]
    [SugarColumn(IsPrimaryKey =true,IsOnlyIgnoreInsert =true,ColumnName ="_id")]
    public string Id { get; set; } // ObjectId 类型存储
}

// ORM 自带的基类 SqlSugar.MongoDbCore 5.1.4.227+
public class MongoDbBaseLong
{
    [SqlSugar.SugarColumn(IsPrimaryKey = true, ColumnName = "_id")]
    public long Id { get; set; } // long 类型可以用 SqlSugar 雪花 ID 插入
}

// ORM 自带的基类 SqlSugar.MongoDbCore 5.1.4.227+
public class MongoDbBaseString
{
    [SqlSugar.SugarColumn(IsPrimaryKey = true, ColumnName = "_id")]
    public string Id { get; set; } // 自定义 string 格式主键
}

// ORM 自带的基类 SqlSugar.MongoDbCore 5.1.4.227+
public class MongoDbBaseGuid
{
    [SqlSugar.SugarColumn(IsPrimaryKey = true, ColumnName = "_id")]
    public Guid Id { get; set; }  // 自定义 Guid 类型主键
}

常见问题

关于事务:

  • 如果需要支持 MongoDB 事务,MongoDB 得部署成副本集才行。

关于如果抛出 <hidden> 错误:

  • 需要把密码中的 @ 替换为 %40

其他关于嵌套对象,无实体查询,多 IP 配置等请参考官方文档。