MdmMirrorWriteScope.cs 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. namespace Admin.NET.Core;
  2. /// <summary>
  3. /// 镜像写入方在范围内更新带外源标记的主数据。页面保存不进入该范围,因此会被只读守卫拒绝。
  4. /// </summary>
  5. public static class MdmMirrorWriteScope
  6. {
  7. private static readonly AsyncLocal<int> Depth = new();
  8. public static bool IsWriter => Depth.Value > 0;
  9. /// <summary>
  10. /// 页面更新或删除 S0 行时,外源行(source_system 非空且不是 AIDOP_NATIVE)拒绝。
  11. /// 只认 Entity.S0 命名空间,避免中立层实体上的同名列被误拦。
  12. /// </summary>
  13. public static void RejectPageWrite(object? entity)
  14. {
  15. if (entity == null || IsWriter)
  16. return;
  17. var type = entity.GetType();
  18. var ns = type.Namespace ?? string.Empty;
  19. if (ns.IndexOf(".Entity.S0", StringComparison.Ordinal) < 0)
  20. return;
  21. var value = type.GetProperty("SourceSystem")?.GetValue(entity) as string;
  22. if (string.IsNullOrWhiteSpace(value))
  23. return;
  24. if (string.Equals(value, "AIDOP_NATIVE", StringComparison.OrdinalIgnoreCase))
  25. return;
  26. throw new InvalidOperationException($"该记录来自 {value},只读");
  27. }
  28. public static IDisposable Enter()
  29. {
  30. Depth.Value++;
  31. return new Popper();
  32. }
  33. private sealed class Popper : IDisposable
  34. {
  35. public void Dispose()
  36. {
  37. if (Depth.Value > 0)
  38. Depth.Value--;
  39. }
  40. }
  41. }