Teigha删除操作完全指南 | 安全彻底清理DWG文件,避免数据灾难!

大家好!在前两篇中我们学习了Teigha的读取和修改操作,今天我们来深入探讨删除操作。删除是CAD文件编辑中最危险的操作,一旦误删可能造成不可逆的数据损失。本文将用最详细的方式教你如何安全、彻底地清理DWG文件。

一、删除前的安全准备

1. 完整的备份系统

cs 复制代码
public class SafeDeleteManager{    private readonly string _originalFilePath;    private string _backupPath;    private readonly List<string> _deletionLog = new List<string>();
    public SafeDeleteManager(string filePath)    {        _originalFilePath = filePath;        CreateBackup();    }
    /// <summary>    /// 创建智能备份    /// </summary>    private void CreateBackup()    {        try        {            string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");            string fileName = Path.GetFileNameWithoutExtension(_originalFilePath);            string directory = Path.GetDirectoryName(_originalFilePath);
            _backupPath = Path.Combine(directory, $"{fileName}_backup_{timestamp}.dwg");            File.Copy(_originalFilePath, _backupPath, true);
            Console.WriteLine($"✅ 已创建备份文件: {_backupPath}");            LogAction($"创建备份: {_backupPath}");        }        catch (Exception ex)        {            throw new Exception($"创建备份失败: {ex.Message}");        }    }
    /// <summary>    /// 执行安全删除操作    /// </summary>    public bool ExecuteSafeDelete(Action<Database, Transaction> deleteAction)    {        try        {            using (Services services = new Services())            using (Database db = new Database(false, true))            {                db.ReadDwgFile(_originalFilePath, FileShare.ReadWrite, true, "");
                using (Transaction tr = db.TransactionManager.StartTransaction())                {                    // 记录删除前的状态                    RecordPreDeletionState(db, tr);
                    // 执行删除操作                    deleteAction(db, tr);
                    tr.Commit();                }
                // 验证删除结果                if (ValidateDeletion(db))                {                    db.SaveAs(_originalFilePath, DwgVersion.Current);                    Console.WriteLine("✅ 删除操作完成并已保存");                    SaveDeletionLog();                    return true;                }                else                {                    RestoreBackup();                    Console.WriteLine("❌ 删除验证失败,已恢复备份");                    return false;                }            }        }        catch (Exception ex)        {            RestoreBackup();            Console.WriteLine($"❌ 删除操作失败,已恢复备份: {ex.Message}");            return false;        }    }
    /// <summary>    /// 记录删除前的状态    /// </summary>    private void RecordPreDeletionState(Database db, Transaction tr)    {        LogAction("=== 删除前状态记录 ===");
        // 记录图层信息        LayerTable layerTable = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);        LogAction($"图层数量: {layerTable.Count}");
        // 记录块信息        BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);        LogAction($"块定义数量: {blockTable.Count}");
        // 记录模型空间实体数量        BlockTableRecord modelSpace = (BlockTableRecord)tr.GetObject(            blockTable[BlockTableRecord.ModelSpace], OpenMode.ForRead);        LogAction($"模型空间实体数量: {modelSpace.Count}");    }
    /// <summary>    /// 验证删除结果    /// </summary>    private bool ValidateDeletion(Database db)    {        using (Transaction tr = db.TransactionManager.StartTransaction())        {            try            {                // 检查数据库完整性                LayerTable layerTable = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);                BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                // 基本验证:确保还有图层和模型空间                if (layerTable.Count == 0)                {                    LogAction("❌ 验证失败:所有图层已被删除");                    return false;                }
                if (!blockTable.Has(BlockTableRecord.ModelSpace))                {                    LogAction("❌ 验证失败:模型空间不存在");                    return false;                }
                LogAction("✅ 删除验证通过");                return true;            }            catch (Exception ex)            {                LogAction($"❌ 验证过程中出错: {ex.Message}");                return false;            }        }    }
    /// <summary>    /// 恢复备份    /// </summary>    private void RestoreBackup()    {        try        {            if (File.Exists(_backupPath))            {                File.Copy(_backupPath, _originalFilePath, true);                LogAction($"已从备份恢复: {_backupPath}");            }        }        catch (Exception ex)        {            LogAction($"恢复备份失败: {ex.Message}");        }    }
    /// <summary>    /// 记录操作日志    /// </summary>    private void LogAction(string message)    {        string timestamp = DateTime.Now.ToString("HH:mm:ss");        string logEntry = $"[{timestamp}] {message}";        _deletionLog.Add(logEntry);        Console.WriteLine(logEntry);    }
    /// <summary>    /// 保存删除日志    /// </summary>    private void SaveDeletionLog()    {        try        {            string logPath = Path.ChangeExtension(_originalFilePath, ".deletion.log");            File.WriteAllLines(logPath, _deletionLog);            Console.WriteLine($"✅ 删除日志已保存: {logPath}");        }        catch (Exception ex)        {            Console.WriteLine($"❌ 保存删除日志失败: {ex.Message}");        }    }
    /// <summary>    /// 清理备份文件(可选)    /// </summary>    public void CleanupBackup()    {        try        {            if (File.Exists(_backupPath))            {                File.Delete(_backupPath);                Console.WriteLine($"✅ 备份文件已清理: {_backupPath}");            }        }        catch (Exception ex)        {            Console.WriteLine($"清理备份文件失败: {ex.Message}");        }    }}
二、图层删除详解

1. 安全图层删除器

cs 复制代码
public class LayerDeletionManager{    /// <summary>    /// 安全删除图层(带完整验证)    /// </summary>    public static DeletionResult DeleteLayerSafely(Database db, Transaction tr, string layerName)    {        var result = new DeletionResult();
        try        {            LayerTable layerTable = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForWrite);
            // 验证图层是否存在            if (!layerTable.Has(layerName))            {                result.Success = false;                result.Message = $"图层 '{layerName}' 不存在";                return result;            }
            ObjectId layerId = layerTable[layerName];            LayerTableRecord layer = (LayerTableRecord)tr.GetObject(layerId, OpenMode.ForRead);
            // 验证是否为系统图层            if (IsSystemLayer(layer.Name))            {                result.Success = false;                result.Message = $"不能删除系统图层 '{layer.Name}'";                return result;            }
            // 检查图层使用情况            var usageInfo = CheckLayerUsage(db, tr, layerId);            if (usageInfo.IsUsed)            {                result.Success = false;                result.Message = $"图层 '{layerName}' 正在被使用,无法删除";                result.Details = usageInfo;                return result;            }
            // 执行删除            layer.UpgradeOpen();            layer.Erase();
            result.Success = true;            result.Message = $"成功删除图层: {layerName}";            result.DeletedObjectId = layerId;
            return result;        }        catch (Exception ex)        {            result.Success = false;            result.Message = $"删除图层失败: {ex.Message}";            return result;        }    }
    /// <summary>    /// 检查系统图层    /// </summary>    private static bool IsSystemLayer(string layerName)    {        string[] systemLayers =         {            "0",                    // 默认图层            "DEFPOINTS",           // 定义点图层            "ASHADE",              // 阴影图层            "A$C*"                 // AutoCAD临时图层        };
        return systemLayers.Any(systemLayer =>             systemLayer.Contains('*')                 ? System.Text.RegularExpressions.Regex.IsMatch(layerName, systemLayer.Replace("*", ".*"))                : systemLayer.Equals(layerName, StringComparison.OrdinalIgnoreCase));    }
    /// <summary>    /// 详细检查图层使用情况    /// </summary>    private static LayerUsageInfo CheckLayerUsage(Database db, Transaction tr, ObjectId layerId)    {        var usageInfo = new LayerUsageInfo();
        BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
        foreach (ObjectId blockId in blockTable)        {            BlockTableRecord block = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForRead);            string blockType = GetBlockType(block);
            foreach (ObjectId entityId in block)            {                Entity entity = tr.GetObject(entityId, OpenMode.ForRead) as Entity;                if (entity != null && entity.LayerId == layerId)                {                    usageInfo.IsUsed = true;                    usageInfo.UsedInBlocks.Add(block.Name);                    usageInfo.EntityCount++;                    usageInfo.EntityTypes.Add(entity.GetType().Name);
                    // 记录具体使用情况                    usageInfo.UsageDetails.Add(new EntityUsage                    {                        BlockName = block.Name,                        BlockType = blockType,                        EntityType = entity.GetType().Name,                        EntityId = entityId                    });                }            }        }
        return usageInfo;    }
    /// <summary>    /// 获取块类型描述    /// </summary>    private static string GetBlockType(BlockTableRecord block)    {        if (block.Name == BlockTableRecord.ModelSpace)            return "模型空间";        else if (block.Name.StartsWith(BlockTableRecord.PaperSpace))            return "图纸空间";        else if (block.IsAnonymous)            return "匿名块";        else            return "普通块";    }
    /// <summary>    /// 强制删除图层(包括其中的实体)    /// </summary>    public static DeletionResult ForceDeleteLayer(Database db, Transaction tr, string layerName)    {        var result = new DeletionResult();
        try        {            LayerTable layerTable = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForWrite);
            if (!layerTable.Has(layerName))            {                result.Success = false;                result.Message = $"图层 '{layerName}' 不存在";                return result;            }
            ObjectId layerId = layerTable[layerName];
            // 先删除图层中的所有实体            var deletionStats = DeleteAllEntitiesInLayer(db, tr, layerId);
            // 然后删除图层本身            LayerTableRecord layer = (LayerTableRecord)tr.GetObject(layerId, OpenMode.ForWrite);            layer.Erase();
            result.Success = true;            result.Message = $"强制删除图层完成: {layerName}";            result.Details = deletionStats;            result.DeletedObjectId = layerId;
            return result;        }        catch (Exception ex)        {            result.Success = false;            result.Message = $"强制删除图层失败: {ex.Message}";            return result;        }    }
    /// <summary>    /// 删除图层中的所有实体    /// </summary>    private static LayerDeletionStats DeleteAllEntitiesInLayer(Database db, Transaction tr, ObjectId layerId)    {        var stats = new LayerDeletionStats();
        BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
        foreach (ObjectId blockId in blockTable)        {            BlockTableRecord block = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForWrite);
            // 收集要删除的实体            var entitiesToDelete = new List<ObjectId>();            foreach (ObjectId entityId in block)            {                Entity entity = tr.GetObject(entityId, OpenMode.ForRead) as Entity;                if (entity != null && entity.LayerId == layerId)                {                    entitiesToDelete.Add(entityId);                }            }
            // 执行删除            foreach (ObjectId entityId in entitiesToDelete)            {                Entity entity = tr.GetObject(entityId, OpenMode.ForWrite) as Entity;                string entityType = entity.GetType().Name;
                entity.Erase();                stats.DeletedEntityCount++;
                if (stats.EntityTypeCounts.ContainsKey(entityType))                    stats.EntityTypeCounts[entityType]++;                else                    stats.EntityTypeCounts[entityType] = 1;
                stats.BlocksAffected.Add(block.Name);            }        }
        stats.BlocksAffected = stats.BlocksAffected.Distinct().ToList();        return stats;    }
    /// <summary>    /// 批量删除空图层    /// </summary>    public static BatchDeletionResult DeleteEmptyLayers(Database db, Transaction tr)    {        var result = new BatchDeletionResult();
        try        {            LayerTable layerTable = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForWrite);            var emptyLayers = new List<string>();
            foreach (ObjectId layerId in layerTable)            {                LayerTableRecord layer = (LayerTableRecord)tr.GetObject(layerId, OpenMode.ForRead);
                // 跳过系统图层                if (IsSystemLayer(layer.Name))                    continue;
                // 检查图层是否为空                if (!IsLayerUsed(db, tr, layerId))                {                    emptyLayers.Add(layer.Name);                }            }
            // 删除空图层            foreach (string layerName in emptyLayers)            {                var deletionResult = DeleteLayerSafely(db, tr, layerName);                if (deletionResult.Success)                {                    result.SuccessfulDeletions++;                    result.DeletedItems.Add(layerName);                }                else                {                    result.FailedDeletions++;                    result.Errors.Add($"{layerName}: {deletionResult.Message}");                }            }
            result.TotalProcessed = emptyLayers.Count;            return result;        }        catch (Exception ex)        {            result.Success = false;            result.Message = $"批量删除空图层失败: {ex.Message}";            return result;        }    }
    /// <summary>    /// 简化版图层使用检查    /// </summary>    private static bool IsLayerUsed(Database db, Transaction tr, ObjectId layerId)    {        BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
        foreach (ObjectId blockId in blockTable)        {            BlockTableRecord block = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForRead);
            foreach (ObjectId entityId in block)            {                Entity entity = tr.GetObject(entityId, OpenMode.ForRead) as Entity;                if (entity != null && entity.LayerId == layerId)                {                    return true;                }            }        }
        return false;    }}
// 删除结果类public class DeletionResult{    public bool Success { get; set; }    public string Message { get; set; }    public ObjectId DeletedObjectId { get; set; }    public object Details { get; set; }}
// 图层使用信息public class LayerUsageInfo{    public bool IsUsed { get; set; }    public int EntityCount { get; set; }    public List<string> UsedInBlocks { get; set; } = new List<string>();    public List<string> EntityTypes { get; set; } = new List<string>();    public List<EntityUsage> UsageDetails { get; set; } = new List<EntityUsage>();}
public class EntityUsage{    public string BlockName { get; set; }    public string BlockType { get; set; }    public string EntityType { get; set; }    public ObjectId EntityId { get; set; }}
// 图层删除统计public class LayerDeletionStats{    public int DeletedEntityCount { get; set; }    public Dictionary<string, int> EntityTypeCounts { get; set; } = new Dictionary<string, int>();    public List<string> BlocksAffected { get; set; } = new List<string>();}
// 批量删除结果public class BatchDeletionResult{    public bool Success { get; set; } = true;    public string Message { get; set; }    public int TotalProcessed { get; set; }    public int SuccessfulDeletions { get; set; }    public int FailedDeletions { get; set; }    public List<string> DeletedItems { get; set; } = new List<string>();    public List<string> Errors { get; set; } = new List<string>();}
三、实体删除详解

1. 实体删除管理器

cs 复制代码
public class EntityDeletionManager{    /// <summary>    /// 按类型删除实体    /// </summary>    public static EntityDeletionResult DeleteEntitiesByType(Database db, Transaction tr, Type entityType,         string specificBlock = null)    {        var result = new EntityDeletionResult { TargetType = entityType.Name };
        try        {            BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
            foreach (ObjectId blockId in blockTable)            {                BlockTableRecord block = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForRead);
                // 如果指定了特定块,只处理该块                if (!string.IsNullOrEmpty(specificBlock) && block.Name != specificBlock)                    continue;
                // 收集要删除的实体                var entitiesToDelete = new List<ObjectId>();                foreach (ObjectId entityId in block)                {                    Entity entity = tr.GetObject(entityId, OpenMode.ForRead) as Entity;                    if (entity != null && entity.GetType() == entityType)                    {                        entitiesToDelete.Add(entityId);                    }                }
                // 执行删除                if (entitiesToDelete.Count > 0)                {                    block.UpgradeOpen();
                    foreach (ObjectId entityId in entitiesToDelete)                    {                        Entity entity = tr.GetObject(entityId, OpenMode.ForWrite) as Entity;                        string layerName = GetLayerName(db, tr, entity.LayerId);
                        entity.Erase();                        result.DeletedCount++;
                        // 记录删除详情                        result.DeletionDetails.Add(new EntityDeletionDetail                        {                            EntityId = entityId,                            EntityType = entityType.Name,                            BlockName = block.Name,                            LayerName = layerName,                            DeletionTime = DateTime.Now                        });                    }
                    result.AffectedBlocks.Add(block.Name);                }            }
            result.Success = true;            result.Message = $"成功删除 {result.DeletedCount} 个 {entityType.Name} 实体";
            return result;        }        catch (Exception ex)        {            result.Success = false;            result.Message = $"按类型删除实体失败: {ex.Message}";            return result;        }    }
    /// <summary>    /// 按条件删除实体    /// </summary>    public static EntityDeletionResult DeleteEntitiesByCondition(Database db, Transaction tr,         Func<Entity, bool> condition, string conditionDescription = "自定义条件")    {        var result = new EntityDeletionResult { TargetType = conditionDescription };
        try        {            BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
            foreach (ObjectId blockId in blockTable)            {                BlockTableRecord block = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForRead);
                // 收集要删除的实体                var entitiesToDelete = new List<ObjectId>();                foreach (ObjectId entityId in block)                {                    Entity entity = tr.GetObject(entityId, OpenMode.ForRead) as Entity;                    if (entity != null && condition(entity))                    {                        entitiesToDelete.Add(entityId);                    }                }
                // 执行删除                if (entitiesToDelete.Count > 0)                {                    block.UpgradeOpen();
                    foreach (ObjectId entityId in entitiesToDelete)                    {                        Entity entity = tr.GetObject(entityId, OpenMode.ForWrite) as Entity;                        entity.Erase();                        result.DeletedCount++;
                        result.DeletionDetails.Add(new EntityDeletionDetail                        {                            EntityId = entityId,                            EntityType = entity.GetType().Name,                            BlockName = block.Name,                            LayerName = GetLayerName(db, tr, entity.LayerId),                            DeletionTime = DateTime.Now                        });                    }
                    result.AffectedBlocks.Add(block.Name);                }            }
            result.Success = true;            result.Message = $"根据条件 '{conditionDescription}' 删除了 {result.DeletedCount} 个实体";
            return result;        }        catch (Exception ex)        {            result.Success = false;            result.Message = $"按条件删除实体失败: {ex.Message}";            return result;        }    }
    /// <summary>    /// 删除短直线(按长度)    /// </summary>    public static EntityDeletionResult DeleteShortLines(Database db, Transaction tr, double minLength)    {        return DeleteEntitiesByCondition(db, tr,             entity => entity is Line line && line.Length < minLength,            $"短直线(长度<{minLength})");    }
    /// <summary>    /// 删除小圆(按半径)    /// </summary>    public static EntityDeletionResult DeleteSmallCircles(Database db, Transaction tr, double minRadius)    {        return DeleteEntitiesByCondition(db, tr,            entity => entity is Circle circle && circle.Radius < minRadius,            $"小圆(半径<{minRadius})");    }
    /// <summary>    /// 删除特定图层上的实体    /// </summary>    public static EntityDeletionResult DeleteEntitiesByLayer(Database db, Transaction tr, string layerName)    {        ObjectId layerId = GetLayerId(db, tr, layerName);        if (layerId.IsNull)        {            return new EntityDeletionResult             {                 Success = false,                 Message = $"图层 '{layerName}' 不存在",                TargetType = $"图层 '{layerName}' 上的实体"            };        }
        return DeleteEntitiesByCondition(db, tr,            entity => entity.LayerId == layerId,            $"图层 '{layerName}' 上的实体");    }
    /// <summary>    /// 删除重复实体(基于位置和类型)    /// </summary>    public static EntityDeletionResult DeleteDuplicateEntities(Database db, Transaction tr, double tolerance = 0.001)    {        var result = new EntityDeletionResult { TargetType = "重复实体" };
        try        {            BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);            BlockTableRecord modelSpace = (BlockTableRecord)tr.GetObject(                blockTable[BlockTableRecord.ModelSpace], OpenMode.ForRead);
            // 收集所有实体及其位置信息            var entityPositions = new Dictionary<string, List<ObjectId>>();
            foreach (ObjectId entityId in modelSpace)            {                Entity entity = tr.GetObject(entityId, OpenMode.ForRead) as Entity;                if (entity != null)                {                    string positionKey = GetEntityPositionKey(entity, tolerance);                    if (!string.IsNullOrEmpty(positionKey))                    {                        if (!entityPositions.ContainsKey(positionKey))                            entityPositions[positionKey] = new List<ObjectId>();
                        entityPositions[positionKey].Add(entityId);                    }                }            }
            // 删除重复实体(每个位置只保留一个)            modelSpace.UpgradeOpen();
            foreach (var kvp in entityPositions)            {                if (kvp.Value.Count > 1)                {                    // 保留第一个,删除其余的                    for (int i = 1; i < kvp.Value.Count; i++)                    {                        Entity entity = tr.GetObject(kvp.Value[i], OpenMode.ForWrite) as Entity;                        entity.Erase();                        result.DeletedCount++;
                        result.DeletionDetails.Add(new EntityDeletionDetail                        {                            EntityId = kvp.Value[i],                            EntityType = entity.GetType().Name,                            BlockName = "ModelSpace",                            LayerName = GetLayerName(db, tr, entity.LayerId),                            DeletionTime = DateTime.Now,                            Notes = "重复实体"                        });                    }
                    result.AffectedBlocks.Add("ModelSpace");                }            }
            result.Success = true;            result.Message = $"删除了 {result.DeletedCount} 个重复实体";
            return result;        }        catch (Exception ex)        {            result.Success = false;            result.Message = $"删除重复实体失败: {ex.Message}";            return result;        }    }
    /// <summary>    /// 获取实体位置键(用于重复检测)    /// </summary>    private static string GetEntityPositionKey(Entity entity, double tolerance)    {        switch (entity)        {            case Line line:                return $"Line_{Math.Round(line.StartPoint.X / tolerance)}_{Math.Round(line.StartPoint.Y / tolerance)}_{Math.Round(line.EndPoint.X / tolerance)}_{Math.Round(line.EndPoint.Y / tolerance)}";
            case Circle circle:                return $"Circle_{Math.Round(circle.Center.X / tolerance)}_{Math.Round(circle.Center.Y / tolerance)}_{Math.Round(circle.Radius / tolerance)}";
            case DBText text:                return $"Text_{Math.Round(text.Position.X / tolerance)}_{Math.Round(text.Position.Y / tolerance)}_{text.TextString}";
            case BlockReference blockRef:                return $"Block_{blockRef.Name}_{Math.Round(blockRef.Position.X / tolerance)}_{Math.Round(blockRef.Position.Y / tolerance)}";
            default:                return null;        }    }
    /// <summary>    /// 获取图层ID    /// </summary>    private static ObjectId GetLayerId(Database db, Transaction tr, string layerName)    {        LayerTable layerTable = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);        return layerTable.Has(layerName) ? layerTable[layerName] : ObjectId.Null;    }
    /// <summary>    /// 获取图层名称    /// </summary>    private static string GetLayerName(Database db, Transaction tr, ObjectId layerId)    {        if (layerId.IsValid && !layerId.IsNull)        {            LayerTableRecord layer = tr.GetObject(layerId, OpenMode.ForRead) as LayerTableRecord;            return layer?.Name ?? "未知图层";        }        return "无图层";    }}
// 实体删除结果public class EntityDeletionResult{    public bool Success { get; set; }    public string Message { get; set; }    public string TargetType { get; set; }    public int DeletedCount { get; set; }    public List<string> AffectedBlocks { get; set; } = new List<string>();    public List<EntityDeletionDetail> DeletionDetails { get; set; } = new List<EntityDeletionDetail>();}
public class EntityDeletionDetail{    public ObjectId EntityId { get; set; }    public string EntityType { get; set; }    public string BlockName { get; set; }    public string LayerName { get; set; }    public DateTime DeletionTime { get; set; }    public string Notes { get; set; }}
四、块定义删除详解

1. 块定义删除管理器

cs 复制代码
public class BlockDeletionManager{    /// <summary>    /// 删除未使用的块定义    /// </summary>    public static BlockDeletionResult DeleteUnusedBlocks(Database db, Transaction tr)    {        var result = new BlockDeletionResult();
        try        {            BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite);            var unusedBlocks = new List<BlockTableRecord>();
            // 查找未使用的块            foreach (ObjectId blockId in blockTable)            {                BlockTableRecord block = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForRead);
                // 跳过系统块                if (IsSystemBlock(block))                    continue;
                // 检查块是否被引用                if (!IsBlockReferenced(db, tr, blockId))                {                    unusedBlocks.Add(block);                }            }
            // 删除未使用的块            foreach (BlockTableRecord block in unusedBlocks)            {                try                {                    block.UpgradeOpen();                    string blockName = block.Name;                    block.Erase();
                    result.DeletedBlocks.Add(blockName);                    result.SuccessfulDeletions++;
                    Console.WriteLine($"✅ 删除未使用的块: {blockName}");                }                catch (Exception ex)                {                    result.FailedDeletions++;                    result.Errors.Add($"删除块 '{block.Name}' 失败: {ex.Message}");                }            }
            result.TotalProcessed = unusedBlocks.Count;            result.Success = true;            result.Message = $"删除了 {result.SuccessfulDeletions} 个未使用的块定义";
            return result;        }        catch (Exception ex)        {            result.Success = false;            result.Message = $"删除未使用块失败: {ex.Message}";            return result;        }    }
    /// <summary>    /// 检查系统块    /// </summary>    private static bool IsSystemBlock(BlockTableRecord block)    {        string[] systemBlocks =         {            BlockTableRecord.ModelSpace,            BlockTableRecord.PaperSpace,            "*Model_Space",            "*Paper_Space"        };
        return systemBlocks.Contains(block.Name) || block.IsAnonymous || block.Name.StartsWith("*");    }
    /// <summary>    /// 检查块是否被引用    /// </summary>    private static bool IsBlockReferenced(Database db, Transaction tr, ObjectId blockId)    {        BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
        foreach (ObjectId spaceId in blockTable)        {            BlockTableRecord space = (BlockTableRecord)tr.GetObject(spaceId, OpenMode.ForRead);
            foreach (ObjectId entityId in space)            {                if (entity is BlockReference blockRef && blockRef.BlockTableRecord == blockId)                {                    return true;                }            }        }
        return false;    }
    /// <summary>    /// 删除指定的块定义    /// </summary>    public static BlockDeletionResult DeleteSpecificBlock(Database db, Transaction tr, string blockName)    {        var result = new BlockDeletionResult();
        try        {            BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite);
            if (!blockTable.Has(blockName))            {                result.Success = false;                result.Message = $"块定义 '{blockName}' 不存在";                return result;            }
            ObjectId blockId = blockTable[blockName];            BlockTableRecord block = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForRead);
            // 检查是否为系统块            if (IsSystemBlock(block))            {                result.Success = false;                result.Message = $"不能删除系统块 '{blockName}'";                return result;            }
            // 检查块是否被引用            if (IsBlockReferenced(db, tr, blockId))            {                result.Success = false;                result.Message = $"块 '{blockName}' 正在被使用,无法删除";                return result;            }
            // 执行删除            block.UpgradeOpen();            block.Erase();
            result.Success = true;            result.Message = $"成功删除块定义: {blockName}";            result.DeletedBlocks.Add(blockName);            result.SuccessfulDeletions = 1;            result.TotalProcessed = 1;
            return result;        }        catch (Exception ex)        {            result.Success = false;            result.Message = $"删除块定义失败: {ex.Message}";            return result;        }    }
    /// <summary>    /// 强制删除块定义(包括所有引用)    /// </summary>    public static BlockDeletionResult ForceDeleteBlock(Database db, Transaction tr, string blockName)    {        var result = new BlockDeletionResult();
        try        {            BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite);
            if (!blockTable.Has(blockName))            {                result.Success = false;                result.Message = $"块定义 '{blockName}' 不存在";                return result;            }
            ObjectId blockId = blockTable[blockName];
            // 先删除所有块引用            var referenceDeletion = DeleteAllBlockReferences(db, tr, blockId);
            // 然后删除块定义            BlockTableRecord block = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForWrite);            block.Erase();
            result.Success = true;            result.Message = $"强制删除块完成: {blockName}";            result.DeletedBlocks.Add(blockName);            result.SuccessfulDeletions = 1;            result.TotalProcessed = 1;            result.Details = referenceDeletion;
            return result;        }        catch (Exception ex)        {            result.Success = false;            result.Message = $"强制删除块失败: {ex.Message}";            return result;        }    }
    /// <summary>    /// 删除所有块引用    /// </summary>    private static BlockReferenceDeletionStats DeleteAllBlockReferences(Database db, Transaction tr, ObjectId blockId)    {        var stats = new BlockReferenceDeletionStats();
        BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
        foreach (ObjectId spaceId in blockTable)        {            BlockTableRecord space = (BlockTableRecord)tr.GetObject(spaceId, OpenMode.ForWrite);
            // 收集要删除的块引用            var referencesToDelete = new List<ObjectId>();            foreach (ObjectId entityId in space)            {                if (entity is BlockReference blockRef && blockRef.BlockTableRecord == blockId)                {                    referencesToDelete.Add(entityId);                }            }
            // 执行删除            foreach (ObjectId refId in referencesToDelete)            {                BlockReference blockRef = (BlockReference)tr.GetObject(refId, OpenMode.ForWrite);                string layerName = GetLayerName(db, tr, blockRef.LayerId);
                blockRef.Erase();                stats.DeletedReferenceCount++;
                stats.DeletionDetails.Add(new BlockReferenceDeletionDetail                {                    BlockName = blockRef.Name,                    LayerName = layerName,                    Position = blockRef.Position,                    DeletionTime = DateTime.Now                });            }        }
        return stats;    }
    /// <summary>    /// 获取图层名称    /// </summary>    private static string GetLayerName(Database db, Transaction tr, ObjectId layerId)    {        if (layerId.IsValid && !layerId.IsNull)        {            LayerTableRecord layer = tr.GetObject(layerId, OpenMode.ForRead) as LayerTableRecord;            return layer?.Name ?? "未知图层";        }        return "无图层";    }}
// 块删除结果public class BlockDeletionResult{    public bool Success { get; set; }    public string Message { get; set; }    public int TotalProcessed { get; set; }    public int SuccessfulDeletions { get; set; }    public int FailedDeletions { get; set; }    public List<string> DeletedBlocks { get; set; } = new List<string>();    public List<string> Errors { get; set; } = new List<string>();    public object Details { get; set; }}
// 块引用删除统计public class BlockReferenceDeletionStats{    public int DeletedReferenceCount { get; set; }    public List<BlockReferenceDeletionDetail> DeletionDetails { get; set; } = new List<BlockReferenceDeletionDetail>();}
public class BlockReferenceDeletionDetail{    public string BlockName { get; set; }    public string LayerName { get; set; }    public Point3d Position { get; set; }    public DateTime DeletionTime { get; set; }}
五、批量删除和清理工具

1. 综合清理工具

cs 复制代码
public class ComprehensiveCleaner{    /// <summary>    /// 执行全面清理    /// </summary>    public static CleanupResult PerformComprehensiveCleanup(Database db, Transaction tr)    {        var result = new CleanupResult();
        try        {            Console.WriteLine("开始全面清理...");
            // 1. 删除未使用的块定义            Console.WriteLine("1. 清理未使用的块定义...");            var blockResult = BlockDeletionManager.DeleteUnusedBlocks(db, tr);            result.BlockCleanup = blockResult;
            // 2. 删除空图层            Console.WriteLine("2. 清理空图层...");            var layerResult = LayerDeletionManager.DeleteEmptyLayers(db, tr);            result.LayerCleanup = layerResult;
            // 3. 删除重复实体            Console.WriteLine("3. 清理重复实体...");            var duplicateResult = EntityDeletionManager.DeleteDuplicateEntities(db, tr);            result.DuplicateCleanup = duplicateResult;
            // 4. 清理废弃对象            Console.WriteLine("4. 清理废弃对象...");            var purgeResult = PurgeDatabase(db);            result.PurgeResult = purgeResult;
            result.Success = true;            result.Message = "全面清理完成";
            return result;        }        catch (Exception ex)        {            result.Success = false;            result.Message = $"全面清理失败: {ex.Message}";            return result;        }    }
    /// <summary>    /// 清理数据库废弃对象    /// </summary>    private static PurgeResult PurgeDatabase(Database db)    {        var result = new PurgeResult();
        try        {            // 记录清理前状态            using (Transaction tr = db.TransactionManager.StartTransaction())            {                result.BeforePurgeStats = GetDatabaseStats(db, tr);                tr.Commit();            }
            // 执行清理            db.Purge(null);
            // 记录清理后状态            using (Transaction tr = db.TransactionManager.StartTransaction())            {                result.AfterPurgeStats = GetDatabaseStats(db, tr);                tr.Commit();            }
            result.Success = true;            result.Message = "数据库清理完成";
            return result;        }        catch (Exception ex)        {            result.Success = false;            result.Message = $"数据库清理失败: {ex.Message}";            return result;        }    }
    /// <summary>    /// 获取数据库统计信息    /// </summary>    private static DatabaseStats GetDatabaseStats(Database db, Transaction tr)    {        var stats = new DatabaseStats();
        // 图层统计        LayerTable layerTable = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);        stats.LayerCount = layerTable.Count;
        // 块统计        BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);        stats.BlockCount = blockTable.Count;
        // 实体统计        BlockTableRecord modelSpace = (BlockTableRecord)tr.GetObject(            blockTable[BlockTableRecord.ModelSpace], OpenMode.ForRead);        stats.ModelSpaceEntityCount = modelSpace.Count;
        // 线型统计        LinetypeTable linetypeTable = (LinetypeTable)tr.GetObject(db.LinetypeTableId, OpenMode.ForRead);        stats.LinetypeCount = linetypeTable.Count;
        // 文字样式统计        TextStyleTable textStyleTable = (TextStyleTable)tr.GetObject(db.TextStyleTableId, OpenMode.ForRead);        stats.TextStyleCount = textStyleTable.Count;
        return stats;    }
    /// <summary>    /// 按条件批量删除    /// </summary>    public static BatchCleanupResult BatchDeleteByConditions(Database db, Transaction tr, CleanupConditions conditions)    {        var result = new BatchCleanupResult();
        try        {            if (conditions.DeleteShortLines)            {                Console.WriteLine("删除短直线...");                var lineResult = EntityDeletionManager.DeleteShortLines(db, tr, conditions.ShortLineLength);                result.ShortLineCleanup = lineResult;            }
            if (conditions.DeleteSmallCircles)            {                Console.WriteLine("删除小圆...");                var circleResult = EntityDeletionManager.DeleteSmallCircles(db, tr, conditions.SmallCircleRadius);                result.SmallCircleCleanup = circleResult;            }
            if (conditions.DeleteEmptyLayers)            {                Console.WriteLine("删除空图层...");                var layerResult = LayerDeletionManager.DeleteEmptyLayers(db, tr);                result.EmptyLayerCleanup = layerResult;            }
            if (conditions.DeleteUnusedBlocks)            {                Console.WriteLine("删除未使用的块...");                var blockResult = BlockDeletionManager.DeleteUnusedBlocks(db, tr);                result.UnusedBlockCleanup = blockResult;            }
            if (conditions.DeleteDuplicateEntities)            {                Console.WriteLine("删除重复实体...");                var duplicateResult = EntityDeletionManager.DeleteDuplicateEntities(db, tr, conditions.DuplicateTolerance);                result.DuplicateCleanup = duplicateResult;            }
            result.Success = true;            result.Message = "批量删除完成";
            return result;        }        catch (Exception ex)        {            result.Success = false;            result.Message = $"批量删除失败: {ex.Message}";            return result;        }    }}
// 清理结果类public class CleanupResult{    public bool Success { get; set; }    public string Message { get; set; }    public BlockDeletionResult BlockCleanup { get; set; }    public BatchDeletionResult LayerCleanup { get; set; }    public EntityDeletionResult DuplicateCleanup { get; set; }    public PurgeResult PurgeResult { get; set; }}
public class PurgeResult{    public bool Success { get; set; }    public string Message { get; set; }    public DatabaseStats BeforePurgeStats { get; set; }    public DatabaseStats AfterPurgeStats { get; set; }}
public class DatabaseStats{    public int LayerCount { get; set; }    public int BlockCount { get; set; }    public int ModelSpaceEntityCount { get; set; }    public int LinetypeCount { get; set; }    public int TextStyleCount { get; set; }}
public class BatchCleanupResult{    public bool Success { get; set; }    public string Message { get; set; }    public EntityDeletionResult ShortLineCleanup { get; set; }    public EntityDeletionResult SmallCircleCleanup { get; set; }    public BatchDeletionResult EmptyLayerCleanup { get; set; }    public BlockDeletionResult UnusedBlockCleanup { get; set; }    public EntityDeletionResult DuplicateCleanup { get; set; }}
public class CleanupConditions{    public bool DeleteShortLines { get; set; }    public double ShortLineLength { get; set; } = 1.0;
    public bool DeleteSmallCircles { get; set; }    public double SmallCircleRadius { get; set; } = 0.5;
    public bool DeleteEmptyLayers { get; set; }    public bool DeleteUnusedBlocks { get; set; }    public bool DeleteDuplicateEntities { get; set; }    public double DuplicateTolerance { get; set; } = 0.001;}

通过这篇详细的删除操作教程,你现在应该能够:

✅ 安全地进行DWG文件删除操作

✅ 删除图层、实体和块定义

✅ 使用批量删除和清理功能

✅ 通过交互式工具进行删除

✅ 处理删除过程中的错误和异常

记住,删除操作是不可逆的,一定要谨慎操作,并确保有备份!下一篇我们将学习如何向DWG文件中添加新内容。

|---------------------------------------------------------------------------------|---------------------------------------------------------------------------------|
| | |

相关推荐
Mr.Pascal5 小时前
Redis:主动更新,读时更新,定时任务。三种的优劣势对比
数据库·redis·缓存
思成不止于此5 小时前
【MySQL 零基础入门】DQL 核心语法(二):表条件查询与分组查询篇
android·数据库·笔记·学习·mysql
骥龙6 小时前
3.10、构建网络防线:防火墙、WAF 与蜜罐实战
服务器·网络·数据库·网络安全
gugugu.7 小时前
Redis 字符串类型完全指南:从原理到实战应用
数据库·redis·缓存
杨云龙UP7 小时前
MySQL 自动备份与覆盖恢复实战:一套脚本搞定全库/按库备份恢复
linux·运维·数据库·sql·mysql
workflower9 小时前
PostgreSQL 数据库优化
数据库·团队开发·数据库开发·时序数据库·数据库架构
计算机毕设VX:Fegn089510 小时前
计算机毕业设计|基于springboot + vue服装商城系统(源码+数据库+文档)
数据库·vue.js·spring boot·课程设计
哈哈哈笑什么10 小时前
SpringBoot 企业级接口加密【通用、可配置、解耦的组件】「开闭原则+模板方法+拦截器/中间件模式」
java·后端·安全
WX-bisheyuange11 小时前
基于Spring Boot的智慧校园管理系统设计与实现
java·大数据·数据库·毕业设计
BullSmall11 小时前
日志打印IP:安全与合规的最佳实践
网络·tcp/ip·安全