/// <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> /// 将实体数据传输到服务端,由服务端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> /// <param name="p_model"></param> /// <param name="p_entity"></param> /// <returns></returns> static async Task <bool> OnDeleting(SqliteEntitySchema p_model, object p_entity) { try { if (p_model.OnDeleting.ReturnType == typeof(Task)) { await(Task) p_model.OnDeleting.Invoke(p_entity, null); } else { p_model.OnDeleting.Invoke(p_entity, null); } } catch (Exception ex) { if (ex.InnerException is KnownException kex) { Kit.Warn(kex.Message); } else { Kit.Warn(ex.Message); } return(false); } return(true); }
/// <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); }
public static void OnUnhandledException(Exception p_ex) { try { KnownException kex; if ((kex = p_ex as KnownException) != null || (kex = p_ex.InnerException as KnownException) != null) { // 只警告,不保存日志 Kit.Warn(kex.Message); } else { string title; string msg; if (p_ex is ServerException se) { title = se.Title; msg = se.Message; } else { title = "未处理异常"; msg = $"异常消息:{p_ex.Message}\r\n堆栈信息:{p_ex.StackTrace}"; } // 警告、输出监视、保存日志 var notify = new NotifyInfo { NotifyType = NotifyType.Warning, Message = title, DelaySeconds = 5, Link = "查看详细", }; notify.LinkCallback = (e) => { ShowTraceBox(); notify.Close(); }; SysVisual.NotifyList.Add(notify); Kit.Trace(TraceOutType.UnhandledException, title, msg); Log.Error(msg); } } catch { } }
/// <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> /// 批量删除实体,单表或多表,列表类型支持: /// <para>Table<Entity>,单表删除</para> /// <para>List<Entity>,单表删除</para> /// <para>IList,多表删除,成员可为Entity,List<Entity>,Table<Entity>的混合</para> /// </summary> /// <param name="p_list">待删除实体列表</param> /// <param name="p_isNotify">是否提示删除结果</param> /// <returns>true 删除成功</returns> public static Task <bool> BatchDelete(IList p_list, bool p_isNotify = true) { if (p_list == null || p_list.Count == 0) { if (p_isNotify) { Kit.Warn(_saveError); } return(Task.FromResult(false)); } Type tp = p_list.GetType(); if (tp.IsGenericType && tp.GetGenericArguments()[0].IsSubclassOf(typeof(Entity))) { return(BatchDeleteSameType(p_list, p_isNotify)); } return(BatchDeleteMultiTypes(p_list, p_isNotify)); }
/// <summary> /// 保存前外部校验,不合格在外部抛出异常 /// </summary> /// <param name="p_model"></param> /// <param name="p_entity"></param> /// <returns></returns> static async Task <bool> OnSaving(EntitySchema p_model, object p_entity) { try { await(Task) p_model.OnSaving.Invoke(p_entity, null); } catch (Exception ex) { if (ex.InnerException is KnownException kex) { Kit.Warn(kex.Message); } else { Kit.Warn(ex.Message); } return(false); } return(true); }
/// <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> /// 保存实体数据 /// </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 = SqliteEntitySchema.Get(typeof(TEntity)); if (model.OnSaving != null) { // 保存前外部校验,不合格在外部抛出异常 if (!await OnSaving(model, p_entity)) { return(false); } } if (_db.Save(p_entity)) { if (p_isNotify) { Kit.Msg("保存成功!"); } return(true); } if (p_isNotify) { Kit.Warn("保存失败!"); } return(false); }
/// <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 = SqliteEntitySchema.Get(typeof(TEntity)); if (model.OnDeleting != null) { if (!await OnDeleting(model, p_entity)) { return(false); } } bool suc = _db.Delete(p_entity); 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> /// <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> /// 批量删除实体,单表或多表,列表类型支持: /// <para>Table<Entity>,单表删除</para> /// <para>List<Entity>,单表删除</para> /// <para>IList,多表删除,成员可为Entity,List<Entity>,Table<Entity>的混合</para> /// </summary> /// <param name="p_list">待删除实体列表</param> /// <param name="p_isNotify">是否提示删除结果</param> /// <returns>true 删除成功</returns> public static async Task <bool> BatchDelete(IList p_list, bool p_isNotify = true) { if (p_list == null || p_list.Count == 0) { if (p_isNotify) { Kit.Warn(_saveError); } return(false); } // 触发外部删除前处理 Type tp = p_list.GetType(); if (tp.IsGenericType && tp.GetGenericArguments()[0].IsSubclassOf(typeof(Entity))) { // 列表中的实体类型相同 var model = SqliteEntitySchema.Get(tp.GetGenericArguments()[0]); if (model.OnDeleting != null) { foreach (var ci in p_list) { if (!await OnDeleting(model, ci)) { return(false); } } } } else { // 多类型 foreach (var item in p_list) { if (item is Entity entity) { var model = SqliteEntitySchema.Get(item.GetType()); if (model.OnDeleting != null) { if (!await OnDeleting(model, entity)) { return(false); } } } else if (item is IList clist && clist.Count > 0 && (tp = item.GetType()) != null && tp.IsGenericType && tp.GetGenericArguments()[0].IsSubclassOf(typeof(Entity))) { // IList<Entity> 或 Table<Entity> var model = SqliteEntitySchema.Get(tp.GetGenericArguments()[0]); if (model.OnDeleting != null) { foreach (var ci in clist) { if (!await OnDeleting(model, ci)) { return(false); } } } } } } if (_db.BatchDelete(p_list)) { if (p_isNotify) { Kit.Msg("删除成功!"); } return(true); } if (p_isNotify) { Kit.Warn("删除失败!"); } return(false); }
/// <summary> /// 一个事务内批量保存实体数据,根据实体状态执行增改,Table<Entity>支持删除,列表类型支持: /// <para>Table<Entity>,单表增删改</para> /// <para>List<Entity>,单表增改</para> /// <para>IList,多表增删改,成员可为Entity,List<Entity>,Table<Entity>的混合</para> /// </summary> /// <param name="p_list">待保存列表</param> /// <param name="p_isNotify">是否提示保存结果</param> /// <returns>true 保存成功</returns> public static async Task <bool> BatchSave(IList p_list, bool p_isNotify = true) { if (p_list == null || p_list.Count == 0) { if (p_isNotify) { Kit.Warn(_unchangedMsg); } return(false); } // 触发外部保存前处理 Type tp = p_list.GetType(); if (tp.IsGenericType && tp.GetGenericArguments()[0].IsSubclassOf(typeof(Entity))) { // 单表增删改,列表中的实体类型相同 // 不判断列表项数0,因可能Table<Entity>只包含删除列表的情况! // IList<Entity> 或 Table<Entity> var model = SqliteEntitySchema.Get(tp.GetGenericArguments()[0]); if (model.OnSaving != null) { foreach (var ci in p_list) { if (!await OnSaving(model, ci)) { return(false); } } } } else { // 多表增删改 foreach (var item in p_list) { if (item is Entity entity) { if (entity.IsAdded || entity.IsChanged) { var model = SqliteEntitySchema.Get(item.GetType()); if (model.OnSaving != null) { if (!await OnSaving(model, entity)) { return(false); } } } } else if (item is IList clist && (tp = item.GetType()) != null && tp.IsGenericType && tp.GetGenericArguments()[0].IsSubclassOf(typeof(Entity))) { // 不判断列表项数0,因可能Table<Entity>只包含删除列表的情况! // IList<Entity> 或 Table<Entity> var model = SqliteEntitySchema.Get(tp.GetGenericArguments()[0]); if (model.OnSaving != null) { foreach (var ci in clist) { if (!await OnSaving(model, ci)) { return(false); } } } } //else //{ // throw new Exception($"批量保存不支持[{item.GetType().Name}]类型!"); //} } } if (_db.BatchSave(p_list)) { 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> /// <param name="p_val"></param> /// <param name="p_checkChange">是否逐级检查IsChanged状态</param> /// <param name="p_isBinding">是否为绑定状态</param> void SetValueInternal(object p_val, bool p_checkChange, bool p_isBinding) { // 过滤多次赋值现象,当cell的类型为string时,在给val赋值null时,将一直保持初始的string.Empty的值 if (object.Equals(_val, p_val) || (Type == typeof(string) && (string)_val == string.Empty && p_val == null)) { return; } // 类型不同时转换 object val = GetValInternal(p_val, Type); // 外部钩子通常为业务校验、领域事件等,校验失败时触发异常使赋值失败 if (Hook != null) { #if SERVER // 服务端无绑定 Hook.Invoke(Row, new object[] { val }); #else if (!p_isBinding) { // 无绑定时不catch钩子抛出的异常,统一在未处理异常中提示警告信息 Hook.Invoke(Row, new object[] { val }); } else { try { // 绑定时钩子抛出的异常被UWP内部catch,无法统一提示警告信息,故先catch Hook.Invoke(Row, new object[] { p_val }); } catch (Exception ex) { if (ex.InnerException is KnownException kex) { Kit.Warn(kex.Message); } else { Kit.Warn(ex.Message); } // 通知UI重置原值 if (PropertyChanged != null) { #if !UWP // uno变态,必须完整执行一遍赋值,触发两次属性值变化,否则UI不重置!!!浪费半天 var old = OriginalVal; OriginalVal = _val; _val = p_val; PropertyChanged(this, new PropertyChangedEventArgs("Val")); _val = OriginalVal; OriginalVal = old; #endif // 立即调用时无效! Kit.RunAsync(() => PropertyChanged(this, new PropertyChangedEventArgs("Val"))); } // 直接返回,赋值失败 return; } } #endif } // 成功赋值 _val = val; // 向上逐级更新IsChanged状态 if (p_checkChange) { IsChanged = !object.Equals(_val, OriginalVal); } // 触发属性变化事件 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Val")); // 数据项值改变时统一在Table和Row中触发事件 Row.OnValueChanged(this); if (Row.Table != null) { Row.Table.OnValueChanged(this); } }