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);