using System; using System.Collections.Generic; using System.Linq.Expressions; using MongoDB.Bson.Serialization; using MongoDB.Driver; namespace ET { public class DBComponentAwakeSystem : AwakeSystem { public override void Awake(DBComponent self, string dbConnection, string dbName) { self.mongoClient = new MongoClient(dbConnection); self.database = self.mongoClient.GetDatabase(dbName); self.Transfers.Clear(); foreach (Type type in Game.EventSystem.GetTypes()) { if (type == typeof (IDBCollection)) { continue; } if (!typeof(IDBCollection).IsAssignableFrom(type)) { continue; } self.Transfers.Add(type.Name); } DBComponent.Instance = self; } } public class DBComponentDestroySystem: DestroySystem { public override void Destroy(DBComponent self) { DBComponent.Instance = null; self.Transfers.Clear(); } } public static class DBComponentSystem { #region Query public static async ETTask Query(this DBComponent self, long id, string collection = null) where T : Entity { if (collection == null) { collection = typeof(T).Name; } using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.DB, id % DBComponent.TaskCount)) { IAsyncCursor cursor = await self.GetCollection(collection).FindAsync(d => d.Id == id); return await cursor.FirstOrDefaultAsync(); } } public static async ETTask> Query(this DBComponent self, Expression> filter, string collection = null) where T : Entity { if (collection == null) { collection = typeof(T).Name; } using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.DB, RandomHelper.RandInt64() % DBComponent.TaskCount)) { IAsyncCursor cursor = await self.GetCollection(collection).FindAsync(filter); return await cursor.ToListAsync(); } } public static async ETTask> Query(this DBComponent self, long taskId, Expression> filter, string collection = null) where T : Entity { if (collection == null) { collection = typeof(T).Name; } using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.DB, taskId % DBComponent.TaskCount)) { IAsyncCursor cursor = await self.GetCollection(collection).FindAsync(filter); return await cursor.ToListAsync(); } } public static async ETTask Query(this DBComponent self, long id, List collectionNames, List result) { if (collectionNames == null || collectionNames.Count == 0) { return; } using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.DB, id % DBComponent.TaskCount)) { foreach (string collectionName in collectionNames) { IAsyncCursor cursor = await self.GetCollection(collectionName).FindAsync(d => d.Id == id); Entity e = await cursor.FirstOrDefaultAsync(); if (e == null) { continue; } result.Add(e); } } } public static async ETTask> QueryFilter(this DBComponent self, FilterDefinition filter, string collection = null) where T : Entity { using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.DB, RandomHelper.RandInt64() % DBComponent.TaskCount)) { IAsyncCursor cursor = await self.GetCollection(collection).Find(filter).ToCursorAsync(); return await cursor.ToListAsync(); } } public static async ETTask> QueryFilter(this DBComponent self, FilterDefinition filter,SortDefinition sort, string collection = null) where T : Entity { using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.DB, RandomHelper.RandInt64() % DBComponent.TaskCount)) { IAsyncCursor cursor =await self.GetCollection(collection).Find(filter).Sort(sort).ToCursorAsync(); return await cursor.ToListAsync(); } } public static async ETTask> QueryJson(this DBComponent self, string json, string collection = null) where T : Entity { using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.DB, RandomHelper.RandInt64() % DBComponent.TaskCount)) { FilterDefinition filterDefinition = new JsonFilterDefinition(json); IAsyncCursor cursor = await self.GetCollection(collection).FindAsync(filterDefinition); return await cursor.ToListAsync(); } } public static async ETTask> QueryJson(this DBComponent self, long taskId, string json, string collection = null) where T : Entity { using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.DB, taskId % DBComponent.TaskCount)) { FilterDefinition filterDefinition = new JsonFilterDefinition(json); IAsyncCursor cursor = await self.GetCollection(collection).FindAsync(filterDefinition); return await cursor.ToListAsync(); } } public static async ETTask UpdateJson(this DBComponent self, string json, string updateJson,string collection = null) where T : Entity { using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.DB, RandomHelper.RandInt64() % DBComponent.TaskCount)) { FilterDefinition filterDefinition = new JsonFilterDefinition(json); UpdateDefinition updateDefinition = new JsonUpdateDefinition(updateJson); return await self.GetCollection(collection).UpdateManyAsync(filterDefinition,updateDefinition); } } #endregion #region Insert public static async ETTask InsertBatch(this DBComponent self, IEnumerable list, string collection = null) where T: Entity { if (collection == null) { collection = typeof (T).Name; } using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.DB, RandomHelper.RandInt64() % DBComponent.TaskCount)) { await self.GetCollection(collection).InsertManyAsync(list); } } #endregion #region Save public static async ETTask Save(this DBComponent self, T entity, string collection = null) where T : Entity { if (entity == null) { Log.Error($"save entity is null: {typeof (T).Name}"); return; } if (collection == null) { collection = entity.GetType().Name; } using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.DB, entity.Id % DBComponent.TaskCount)) { #pragma warning disable CS0618 // 类型或成员已过时 await self.GetCollection(collection).ReplaceOneAsync(d => d.Id == entity.Id, entity, new UpdateOptions { IsUpsert = true }); #pragma warning restore CS0618 // 类型或成员已过时 } } public static async ETTask Save(this DBComponent self, long taskId, T entity, string collection = null) where T : Entity { if (entity == null) { Log.Error($"save entity is null: {typeof (T).Name}"); return; } if (collection == null) { collection = entity.GetType().Name; } using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.DB, taskId % DBComponent.TaskCount)) { #pragma warning disable CS0618 // 类型或成员已过时 await self.GetCollection(collection).ReplaceOneAsync(d => d.Id == entity.Id, entity, new UpdateOptions { IsUpsert = true }); #pragma warning restore CS0618 // 类型或成员已过时 } } public static async ETTask Save(this DBComponent self, long taskId, List entities) { if (entities == null) { Log.Error($"save entity is null"); return; } using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.DB, taskId % DBComponent.TaskCount)) { foreach (Entity entity in entities) { if (entity == null) { continue; } #pragma warning disable CS0618 // 类型或成员已过时 await self.GetCollection(entity.GetType().Name) .ReplaceOneAsync(d => d.Id == entity.Id, entity, new UpdateOptions { IsUpsert = true }); #pragma warning restore CS0618 // 类型或成员已过时 } } } public static async ETVoid SaveNotWait(this DBComponent self, T entity, long taskId = 0, string collection = null) where T : Entity { if (taskId == 0) { await self.Save(entity, collection); return; } await self.Save(taskId, entity, collection); } #endregion #region Remove public static async ETTask Remove(this DBComponent self, long id, string collection = null) where T : Entity { using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.DB, id % DBComponent.TaskCount)) { DeleteResult result = await self.GetCollection(collection).DeleteOneAsync(d => d.Id == id); return result.DeletedCount; } } public static async ETTask Remove(this DBComponent self, long taskId, long id, string collection = null) where T : Entity { using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.DB, taskId % DBComponent.TaskCount)) { DeleteResult result = await self.GetCollection(collection).DeleteOneAsync(d => d.Id == id); return result.DeletedCount; } } public static async ETTask Remove(this DBComponent self, Expression> filter, string collection = null) where T : Entity { using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.DB, RandomHelper.RandInt64() % DBComponent.TaskCount)) { DeleteResult result = await self.GetCollection(collection).DeleteManyAsync(filter); return result.DeletedCount; } } public static async ETTask Remove(this DBComponent self, long taskId, Expression> filter, string collection = null) where T : Entity { using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.DB, taskId % DBComponent.TaskCount)) { DeleteResult result = await self.GetCollection(collection).DeleteManyAsync(filter); return result.DeletedCount; } } #endregion } }