/// <summary> /// 将实体数据传输到服务端,由服务端DataProvider删除实体,用于需要触发领域事件或同步缓存的情况 /// </summary> /// <typeparam name="TEntity">实体类型</typeparam> /// <param name="p_entity">待删除的行</param> /// <param name="p_isNotify">是否提示删除结果</param> /// <returns>true 删除成功</returns> public static async Task <bool> DeleteBySvc <TEntity>(TEntity p_entity, bool p_isNotify = true) where TEntity : Entity { if (p_entity == null || p_entity.IsAdded) { if (p_isNotify) { Kit.Warn(_saveError); } return(false); } var model = EntitySchema.Get(typeof(TEntity)); bool suc = await new UnaryRpc( typeof(TSvc).Name, "EntityAccess.Delete", p_entity, model.Schema.Name ).Call <bool>(); if (p_isNotify) { if (suc) { Kit.Msg("删除成功!"); } else { Kit.Warn("删除失败!"); } } return(suc); }
/// <summary> /// 根据单主键或唯一索引列删除实体,同步删除缓存,依靠数据库的级联删除自动删除子实体 /// </summary> /// <typeparam name="TEntity">实体类型</typeparam> /// <param name="p_keyName">主键或唯一索引列名</param> /// <param name="p_keyVal">主键值</param> /// <returns>实际删除行数</returns> public async Task <bool> DelByKey <TEntity>(string p_keyName, string p_keyVal) where TEntity : Entity { var model = EntitySchema.Get(typeof(TEntity)); // 有缓存或需要触发实体删除事件 if (model.CacheHandler != null || (model.CudEvent & CudEvent.LocalDelete) == CudEvent.LocalDelete || (model.CudEvent & CudEvent.RemoteDelete) == CudEvent.RemoteDelete) { TEntity entity = null; if (model.CacheHandler != null) { entity = await model.CacheHandler.Get <TEntity>(p_keyName, p_keyVal); } if (entity == null) { entity = await _db.First <TEntity>( $"select * from `{model.Schema.Name}` where {p_keyName}=@{p_keyName}", new Dict { { p_keyName, p_keyVal } }); } if (entity != null) { return(await Delete(entity)); } return(false); } // 无缓存无事件直接删除 return(await _db.Exec( $"delete from `{model.Schema.Name}` where {p_keyName}=@{p_keyName}", new Dict { { p_keyName, p_keyVal } }) == 1); }
/// <summary> /// 保存实体数据 /// </summary> /// <typeparam name="TEntity">实体类型</typeparam> /// <param name="p_entity">待保存的实体</param> /// <returns>是否成功</returns> public async Task <bool> Save <TEntity>(TEntity p_entity) where TEntity : Entity { Throw.If(p_entity == null || (!p_entity.IsAdded && !p_entity.IsChanged), _unchangedMsg); var model = EntitySchema.Get(typeof(TEntity)); if (model.OnSaving != null) { await(Task) model.OnSaving.Invoke(p_entity, null); } Dict dt = model.Schema.GetSaveSql(p_entity); if (await _db.Exec((string)dt["text"], (Dict)dt["params"]) != 1) { return(false); } // 实体事件 GatherSaveEvents(p_entity, model); // 更新实体时删除缓存 if (model.CacheHandler != null && !p_entity.IsAdded && p_entity.IsChanged) { await model.CacheHandler.Remove(p_entity); } p_entity.AcceptChanges(); return(true); }
/// <summary> /// 单表批量删除 /// </summary> /// <param name="p_list"></param> /// <param name="p_isNotify"></param> /// <returns></returns> static async Task <bool> BatchDeleteSameType(IList p_list, bool p_isNotify) { var model = EntitySchema.Get(p_list.GetType().GetGenericArguments()[0]); if (model.OnDeleting != null) { foreach (var item in p_list) { if (item != null && !await OnDeleting(model, item)) { return(false); } } } Dict dt = model.Schema.GetDeleteSql(p_list); bool suc = await BatchExec(new List <Dict> { dt }) > 0; if (p_isNotify) { if (suc) { Kit.Msg("删除成功!"); } else { Kit.Warn("删除失败!"); } } return(suc); }
/// <summary> /// 创建空Table,创建过程: /// <para>Entity已指定Tbl标签时,根据表名查询表结构创建列</para> /// <para>Tbl标签时,按照Entity属性创建列</para> /// </summary> /// <returns>空表</returns> public static Table <TEntity> Create() { var tbl = new Table <TEntity>(); var tp = typeof(TEntity); var attr = tp.GetCustomAttribute <TblAttribute>(false); if (attr == null || string.IsNullOrEmpty(attr.Name)) { // 不包括继承的属性,含Set var props = tp.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty | BindingFlags.DeclaredOnly); foreach (var p in props) { tbl.Columns.Add(new Column(p.Name, p.PropertyType)); } } else { PropertyInfo prop; var model = EntitySchema.Get(tp); foreach (var col in model.Schema.PrimaryKey.Concat(model.Schema.Columns)) { var colType = col.Type; if (colType == typeof(byte) && (prop = typeof(TEntity).GetProperty(col.Name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.IgnoreCase)) != null) { // Entity 时根据属性类型将 byte 自动转为 enum 类型 colType = prop.PropertyType; } tbl.Columns.Add(new Column(col.Name, colType)); } } return(tbl); }
/// <summary> /// 单表增删改,列表中的实体类型相同 /// </summary> /// <param name="p_list"></param> /// <param name="p_isNotify"></param> /// <returns></returns> static async Task <bool> BatchSaveSameType(IList p_list, bool p_isNotify) { var model = EntitySchema.Get(p_list.GetType().GetGenericArguments()[0]); if (model.OnSaving != null) { foreach (var item in p_list) { if (item != null && !await OnSaving(model, item)) { return(false); } } } var dts = model.Schema.GetBatchSaveSql(p_list); // 不需要保存 if (dts == null || dts.Count == 0) { if (p_isNotify) { Kit.Msg(_unchangedMsg); } return(false); } if (await BatchExec(dts) > 0) { if (p_list is Table tbl) { tbl.AcceptChanges(); } else { foreach (var row in p_list.OfType <Row>()) { if (row.IsChanged || row.IsAdded) { row.AcceptChanges(); } } } if (p_isNotify) { Kit.Msg("保存成功!"); } return(true); } if (p_isNotify) { Kit.Warn("保存失败!"); } return(false); }
/// <summary> /// 返回所有实体列表 /// </summary> /// <typeparam name="TEntity">实体类型</typeparam> /// <returns></returns> public static Task <Table <TEntity> > GetAll <TEntity>() where TEntity : Entity { return(new UnaryRpc( typeof(TSvc).Name, "Da.Query", EntitySchema.Get(typeof(TEntity)).Schema.GetSelectAllSql(), null ).Call <Table <TEntity> >()); }
/// <summary> /// 根据主键删除实体对象,仅支持单主键id,依靠数据库的级联删除自动删除子实体 /// </summary> /// <typeparam name="TEntity">实体类型</typeparam> /// <param name="p_id">主键</param> /// <param name="p_isNotify">是否提示删除结果</param> /// <returns>true 删除成功</returns> public static async Task <bool> DelByID <TEntity>(long p_id, bool p_isNotify = true) { var model = EntitySchema.Get(typeof(TEntity)); bool suc = await Exec(model.Schema.SqlDelete, new { id = p_id }) == 1; if (p_isNotify) { Kit.Msg(suc ? "删除成功!" : "删除失败!"); } return(suc); }
/// <summary> /// 单表批量删除 /// </summary> /// <param name="p_list"></param> /// <returns></returns> async Task <int> BatchDeleteSameType(IList p_list) { var model = EntitySchema.Get(p_list.GetType().GetGenericArguments()[0]); if (model.OnDeleting != null) { foreach (var item in p_list) { await(Task) model.OnDeleting.Invoke(item, null); } } Dict dt = model.Schema.GetDeleteSql(p_list); return(await BatchExecDelete(dt, p_list, model)); }
/// <summary> /// 保存实体数据 /// </summary> /// <typeparam name="TEntity">实体类型</typeparam> /// <param name="p_entity">待保存的实体</param> /// <param name="p_isNotify">是否提示保存结果</param> /// <returns>是否成功</returns> public static async Task <bool> Save <TEntity>(TEntity p_entity, bool p_isNotify = true) where TEntity : Entity { if (p_entity == null || (!p_entity.IsAdded && !p_entity.IsChanged)) { if (p_isNotify) { Kit.Warn(_unchangedMsg); } return(false); } var model = EntitySchema.Get(typeof(TEntity)); if (model.OnSaving != null) { // 保存前外部校验,不合格在外部抛出异常 if (!await OnSaving(model, p_entity)) { return(false); } } Dict dt = model.Schema.GetSaveSql(p_entity); int cnt = await Exec((string)dt["text"], (Dict)dt["params"]); if (cnt > 0) { p_entity.AcceptChanges(); if (p_isNotify) { Kit.Msg("保存成功!"); } return(true); } if (p_isNotify) { Kit.Warn("保存失败!"); } return(false); }
/// <summary> /// 多表批量删除 /// </summary> /// <param name="p_list"></param> /// <returns></returns> async Task <int> BatchDeleteMultiTypes(IList p_list) { int cnt = 0; foreach (var item in p_list) { if (item is Entity entity) { var model = EntitySchema.Get(item.GetType()); if (model.OnDeleting != null) { await(Task) model.OnDeleting.Invoke(item, null); } var ls = new List <Row> { entity }; Dict dt = model.Schema.GetDeleteSql(ls); cnt += await BatchExecDelete(dt, ls, model); } else if (item is IList clist && clist.Count > 0) { Type tp = item.GetType(); if (tp.IsGenericType && tp.GetGenericArguments()[0].IsSubclassOf(typeof(Entity))) { // IList<Entity> 或 Table<Entity> var model = EntitySchema.Get(tp.GetGenericArguments()[0]); if (model.OnDeleting != null) { foreach (var ci in clist) { await(Task) model.OnDeleting.Invoke(item, null); } } Dict dt = model.Schema.GetDeleteSql(clist); cnt += await BatchExecDelete(dt, clist, model); } } } return(cnt); }
/// <summary> /// 删除实体,同步删除缓存,依靠数据库的级联删除自动删除子实体 /// </summary> /// <typeparam name="TEntity">实体类型</typeparam> /// <param name="p_entity">待删除的实体</param> /// <returns>true 删除成功</returns> public async Task <bool> Delete <TEntity>(TEntity p_entity) where TEntity : Entity { Throw.IfNull(p_entity, _saveError); var model = EntitySchema.Get(typeof(TEntity)); if (model.OnDeleting != null) { await(Task) model.OnDeleting.Invoke(p_entity, null); } Dict dt = model.Schema.GetDeleteSql(new List <Entity> { p_entity }); return(await BatchExecDelete(dt, new List <Entity> { p_entity }, model) == 1); }
/// <summary> /// 删除实体,依靠数据库的级联删除自动删除子实体 /// </summary> /// <typeparam name="TEntity">实体类型</typeparam> /// <param name="p_entity">待删除的行</param> /// <param name="p_isNotify">是否提示删除结果</param> /// <returns>true 删除成功</returns> public static async Task <bool> Delete <TEntity>(TEntity p_entity, bool p_isNotify = true) where TEntity : Entity { if (p_entity == null || p_entity.IsAdded) { if (p_isNotify) { Kit.Warn(_saveError); } return(false); } var model = EntitySchema.Get(typeof(TEntity)); if (model.OnDeleting != null) { if (!await OnDeleting(model, p_entity)) { return(false); } } Dict dt = model.Schema.GetDeleteSql(new List <Row> { p_entity }); bool suc = await Exec((string)dt["text"], ((List <Dict>)dt["params"])[0]) == 1; if (p_isNotify) { if (suc) { Kit.Msg("删除成功!"); } else { Kit.Warn("删除失败!"); } } return(suc); }
/// <summary> /// 将实体数据传输到服务端,由服务端DataProvider保存实体,用于需要触发领域事件或同步缓存的情况 /// </summary> /// <typeparam name="TEntity">实体类型</typeparam> /// <param name="p_entity">待保存的实体</param> /// <param name="p_isNotify">是否提示保存结果</param> /// <returns>是否成功</returns> public static async Task <bool> SaveBySvc <TEntity>(TEntity p_entity, bool p_isNotify = true) where TEntity : Entity { if (p_entity == null || (!p_entity.IsAdded && !p_entity.IsChanged)) { if (p_isNotify) { Kit.Warn(_unchangedMsg); } return(false); } var model = EntitySchema.Get(typeof(TEntity)); bool suc = await new UnaryRpc( typeof(TSvc).Name, "EntityAccess.Save", p_entity, model.Schema.Name ).Call <bool>(); if (suc) { p_entity.AcceptChanges(); if (p_isNotify) { Kit.Msg("保存成功!"); } return(true); } if (p_isNotify) { Kit.Warn("保存失败!"); } return(false); }
/// <summary> /// 单表增删改,列表中的实体类型相同 /// </summary> /// <param name="p_list"></param> /// <returns></returns> async Task <bool> BatchSaveSameType(IList p_list) { var model = EntitySchema.Get(p_list.GetType().GetGenericArguments()[0]); if (model.OnSaving != null) { foreach (var item in p_list) { await(Task) model.OnSaving.Invoke(item, null); } } var dts = model.Schema.GetBatchSaveSql(p_list); // 不需要保存 if (dts == null || dts.Count == 0) { Throw.Msg(_unchangedMsg); } await BatchExec(dts); // 实体事件、缓存 foreach (var entity in p_list.OfType <Entity>()) { if (entity.IsChanged || entity.IsAdded) { await ApplyEventAndCache(entity, model); } } if (p_list is Table tbl) { tbl.DeletedRows?.Clear(); } return(true); }
/// <summary> /// 根据主键或唯一索引列获得实体对象(包含所有列值),仅支持单主键 /// 不存在时返回null,启用缓存时首先从缓存中获取 /// </summary> /// <typeparam name="TEntity">实体类型</typeparam> /// <param name="p_keyName">主键列名</param> /// <param name="p_keyVal">主键值</param> /// <returns>返回实体对象或null</returns> public async Task <TEntity> GetByKey <TEntity>(string p_keyName, string p_keyVal) where TEntity : Entity { var model = EntitySchema.Get(typeof(TEntity)); TEntity entity = null; if (model.CacheHandler != null) { entity = await model.CacheHandler.Get <TEntity>(p_keyName, p_keyVal); } if (entity == null) { entity = await _db.First <TEntity>( $"select * from `{model.Schema.Name}` where {p_keyName}=@{p_keyName}", new Dict { { p_keyName, p_keyVal } }); if (entity != null && model.CacheHandler != null) { await model.CacheHandler.Cache(entity); } } return(entity); }
/// <summary> /// 根据主键获得实体对象(包含所有列值),仅支持单主键id,不存在时返回null /// </summary> /// <typeparam name="TEntity">实体类型</typeparam> /// <param name="p_id">主键</param> /// <returns>返回实体对象或null</returns> public static Task <TEntity> GetByID <TEntity>(long p_id) where TEntity : Entity { return(First <TEntity>(EntitySchema.Get(typeof(TEntity)).Schema.SqlSelect, new { id = p_id })); }
/// <summary> /// 多表增删改 /// </summary> /// <param name="p_list"></param> /// <returns></returns> async Task <bool> BatchSaveMultiTypes(IList p_list) { var dts = new List <Dict>(); foreach (var item in p_list) { if (item is Entity entity) { if (entity.IsAdded || entity.IsChanged) { var model = EntitySchema.Get(item.GetType()); if (model.OnSaving != null) { await(Task) model.OnSaving.Invoke(entity, null); } dts.Add(model.Schema.GetSaveSql(entity)); } } else if (item is IList clist) { // 不判断列表项数0,因可能Table<Entity>只包含删除列表的情况! Type tp = item.GetType(); if (tp.IsGenericType && tp.GetGenericArguments()[0].IsSubclassOf(typeof(Entity))) { // IList<Entity> 或 Table<Entity> var model = EntitySchema.Get(tp.GetGenericArguments()[0]); if (model.OnSaving != null) { foreach (var ci in clist) { await(Task) model.OnSaving.Invoke(ci, null); } } var cdts = model.Schema.GetBatchSaveSql(clist); if (cdts != null && cdts.Count > 0) { dts.AddRange(cdts); } } } } // 不需要保存 if (dts == null || dts.Count == 0) { Throw.Msg(_unchangedMsg); } await BatchExec(dts); foreach (var item in p_list) { if (item is Entity entity) { if (entity.IsChanged || entity.IsAdded) { await ApplyEventAndCache(entity, EntitySchema.Get(item.GetType())); } } else if (item is IList clist && clist.Count > 0) { Type tp = item.GetType(); if (tp.IsGenericType && tp.GetGenericArguments()[0].IsSubclassOf(typeof(Entity))) { // IList<Entity> 或 Table<Entity> var model = EntitySchema.Get(tp.GetGenericArguments()[0]); foreach (var row in clist.OfType <Entity>()) { if (row.IsAdded || row.IsChanged) { await ApplyEventAndCache(row, model); } } if (item is Table tbl) { tbl.DeletedRows?.Clear(); } } } } return(true); }
/// <summary> /// 多表增删改 /// </summary> /// <param name="p_list"></param> /// <param name="p_isNotify"></param> /// <returns></returns> static async Task <bool> BatchSaveMultiTypes(IList p_list, bool p_isNotify) { var dts = new List <Dict>(); foreach (var item in p_list) { if (item is Entity entity) { if (entity.IsAdded || entity.IsChanged) { var model = EntitySchema.Get(item.GetType()); if (model.OnSaving != null) { if (!await OnSaving(model, entity)) { return(false); } } dts.Add(model.Schema.GetSaveSql(entity)); } } else if (item is IList clist) { // 不判断列表项数0,因可能Table<Entity>只包含删除列表的情况! Type tp = item.GetType(); if (tp.IsGenericType && tp.GetGenericArguments()[0].IsSubclassOf(typeof(Entity))) { // IList<Entity> 或 Table<Entity> var model = EntitySchema.Get(tp.GetGenericArguments()[0]); if (model.OnSaving != null) { foreach (var ci in clist) { if (!await OnSaving(model, ci)) { return(false); } } } var cdts = model.Schema.GetBatchSaveSql(clist); if (cdts != null && cdts.Count > 0) { dts.AddRange(cdts); } } } } // 不需要保存 if (dts == null || dts.Count == 0) { if (p_isNotify) { Kit.Msg(_unchangedMsg); } return(true); } bool suc = await BatchExec(dts) > 0; if (suc) { foreach (var item in p_list) { if (item is Entity entity) { entity.AcceptChanges(); } else if (item is Table tbl) { tbl.AcceptChanges(); tbl.DeletedRows?.Clear(); } else if (item is IList clist && clist.Count > 0) { foreach (var ci in clist) { if (ci is Row row && (row.IsAdded || row.IsChanged)) { row.AcceptChanges(); } } } } if (p_isNotify) { Kit.Msg("保存成功!"); } return(true); } if (p_isNotify) { Kit.Warn("保存失败!"); } return(false); }
/// <summary> /// 多表批量删除 /// </summary> /// <param name="p_list"></param> /// <param name="p_isNotify"></param> /// <returns></returns> static async Task <bool> BatchDeleteMultiTypes(IList p_list, bool p_isNotify) { var dts = new List <Dict>(); foreach (var item in p_list) { if (item is Entity entity) { var model = EntitySchema.Get(item.GetType()); if (model.OnDeleting != null) { if (!await OnDeleting(model, entity)) { return(false); } } dts.Add(model.Schema.GetDeleteSql(new List <Row> { entity })); } else if (item is IList clist && clist.Count > 0) { Type tp = item.GetType(); if (tp.IsGenericType && tp.GetGenericArguments()[0].IsSubclassOf(typeof(Entity))) { // IList<Entity> 或 Table<Entity> var model = EntitySchema.Get(tp.GetGenericArguments()[0]); if (model.OnDeleting != null) { foreach (var ci in clist) { if (!await OnDeleting(model, ci)) { return(false); } } } dts.Add(model.Schema.GetDeleteSql(clist)); } } } // 不需要删除 if (dts == null || dts.Count == 0) { if (p_isNotify) { Kit.Msg(_unchangedMsg); } return(true); } bool suc = await BatchExec(dts) > 0; if (p_isNotify) { if (suc) { Kit.Msg("删除成功!"); } else { Kit.Warn("删除失败!"); } } return(suc); }
/// <summary> /// 返回所有实体列表 /// </summary> /// <typeparam name="TEntity">实体类型</typeparam> /// <returns></returns> public Task <Table <TEntity> > GetAll <TEntity>() where TEntity : Entity { return(_db.Query <TEntity>(EntitySchema.Get(typeof(TEntity)).Schema.GetSelectAllSql(), null)); }