1、添加协议并生成

打开 InnerMessage.proto 文件,在 DBQueryJsonRequest 下添加协议

message DBSortQueryJsonRequest // IRequest
{
    int32 RpcId = 90;
    string CollectionName = 1;
    string QueryJson = 2;
    string SortJson = 3;
    int32 Count = 4;
}

打开Unity项目,点击菜单栏的 Tools -> Proto2CS 生成协议

2、在Server.Model下的 Module/DB 文件夹下新建 DBSortQueryJsonTask.cs 文件

using System;
using System.Collections.Generic;
using MongoDB.Driver;

namespace ETModel
{
    [ObjectSystem]
    public class DBSortQueryJsonTaskAwakeSystem : AwakeSystem<DBSortQueryJsonTask, string[],int,ETTaskCompletionSource<List<ComponentWithId>>>
    {
        public override void Awake(DBSortQueryJsonTask self, string[] strs,int count, ETTaskCompletionSource<List<ComponentWithId>> tcs)
        {
            self.CollectionName = strs[0];
            self.QueryJson = strs[1];
            self.SortJson = strs[2];
            self.Count = count;
            self.Tcs = tcs; 
        }
    }

    public sealed class DBSortQueryJsonTask : DBTask
    {
        public string CollectionName { get; set; }

        public string QueryJson { get; set; }

        public string SortJson { get; set; }

        public int Count { get; set; }

        public ETTaskCompletionSource<List<ComponentWithId>> Tcs { get; set; }

        public override async ETTask Run()
        {
            DBComponent dbComponent = Game.Scene.GetComponent<DBComponent>();
            try
            {
                FilterDefinition<ComponentWithId> filterDefinition = new JsonFilterDefinition<ComponentWithId>(this.QueryJson);
                SortDefinition<ComponentWithId> sortDefinition = new JsonSortDefinition<ComponentWithId>(this.SortJson);
                IFindFluent<ComponentWithId, ComponentWithId> ifindiluent = dbComponent.GetCollection(this.CollectionName).Find(filterDefinition).Sort(sortDefinition).Limit(this.Count);
                List<ComponentWithId> components = await ifindiluent.ToCursor().ToListAsync();
                this.Tcs.SetResult(components);
            }
            catch (Exception e)
            {
                this.Tcs.SetException(new Exception($"查询数据库异常! {CollectionName} {this.QueryJson}", e));
            }
        }
    }
}

3、在Server.Hotfix下的Module/DB文件夹下新建DBSortQueryJsonRequestHandler.cs文件

using System;
using ETModel;

namespace ETHotfix
{
    [MessageHandler(AppType.DB)]
    public class DBSortQueryJsonRequestHandler : AMRpcHandler<DBSortQueryJsonRequest, DBQueryJsonResponse>
    {
        private readonly string[] strs = new string[3];

        protected override async ETTask Run(Session session, DBSortQueryJsonRequest request, DBQueryJsonResponse response, Action reply)
        {
            strs[0] = request.CollectionName;
            strs[1] = request.QueryJson;
            strs[2] = request.SortJson;
            var list = await Game.Scene.GetComponent<DBComponent>().GetJson(this.strs, request.Count);
            response.Components = list;
            reply();
        }
    }
}

4、修改在Server.Hotfix下的Module/DB文件夹下的DBProxyComponentSystem.cs文件

在 QueryInner 下添加排序查询方法

        //Expression表达式转换时monongb语句
        private static string ExpressionConversionJson<T>(Expression<Func<T, bool>> exp)
        {
            ExpressionFilterDefinition<T> filter = new ExpressionFilterDefinition<T>(exp);
            IBsonSerializerRegistry serializerRegistry = BsonSerializer.SerializerRegistry;
            IBsonSerializer<T> documentSerializer = serializerRegistry.GetSerializer<T>();
            return filter.Render(documentSerializer, serializerRegistry).ToJson();
        }
        
        /// <summary>
        /// 根据json查询条件查询
        /// </summary>
        /// <param name="self"></param>
        /// <param name="json"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static async ETTask<List<T>> SortQuery<T>(this DBProxyComponent self, Expression<Func<T, bool>> queryExp, Expression<Func<T, bool>> sortExp, int count) where T : ComponentWithId
        {
            string queryJson = ExpressionConversionJson(queryExp);
            string sortJson = ExpressionConversionJson(sortExp);
            return await self.SortQuery<T>(typeof(T).Name, queryJson, sortJson, count);
        }

        /// <summary>
        /// 根据json查询条件查询
        /// </summary>
        /// <param name="self"></param>
        /// <param name="json"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static async ETTask<List<T>> SortQuery<T>(this DBProxyComponent self,string typeName,string queryJson, string sortJson, int count) where T : ComponentWithId
        {
            Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(self.dbAddress);
            DBQueryJsonResponse dbQueryJsonResponse = (DBQueryJsonResponse)await session.Call(new DBSortQueryJsonRequest { CollectionName = typeName, QueryJson = queryJson, SortJson = sortJson, Count = count });
            return ConversionType<T>(dbQueryJsonResponse.Components);
        }
        
        /// <summary>
        /// 类型转换
        /// </summary>
        /// <param name="componentWithIds"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static List<T> ConversionType<T>(List<ComponentWithId> componentWithIds) where T : ComponentWithId
        {
            if (componentWithIds == null)
            {
                return null;
            }

            return componentWithIds.Cast<T>().ToList();
        }

查询测试

// 查询UserId最大值 倒序查询 user=> user.UserId == -1
var query = await DBProxyComponent.Inst.SortQuery<User>(user=>true, user=> user.UserId == -1, 1);

// 查询UserId最大值的2条 正序查询 user=> user.UserId == 1
var query = await DBProxyComponent.Inst.SortQuery<User>(user=>true, user=> user.UserId == 1, 2);