namespace Admin.NET.Core;
///
/// 镜像写入方在范围内更新带外源标记的主数据。页面保存不进入该范围,因此会被只读守卫拒绝。
///
public static class MdmMirrorWriteScope
{
private static readonly AsyncLocal Depth = new();
public static bool IsWriter => Depth.Value > 0;
///
/// 页面更新或删除 S0 行时,外源行(source_system 非空且不是 AIDOP_NATIVE)拒绝。
/// 只认 Entity.S0 命名空间,避免中立层实体上的同名列被误拦。
///
public static void RejectPageWrite(object? entity)
{
if (entity == null || IsWriter)
return;
var type = entity.GetType();
var ns = type.Namespace ?? string.Empty;
if (ns.IndexOf(".Entity.S0", StringComparison.Ordinal) < 0)
return;
var value = type.GetProperty("SourceSystem")?.GetValue(entity) as string;
if (string.IsNullOrWhiteSpace(value))
return;
if (string.Equals(value, "AIDOP_NATIVE", StringComparison.OrdinalIgnoreCase))
return;
throw new InvalidOperationException($"该记录来自 {value},只读");
}
public static IDisposable Enter()
{
Depth.Value++;
return new Popper();
}
private sealed class Popper : IDisposable
{
public void Dispose()
{
if (Depth.Value > 0)
Depth.Value--;
}
}
}