You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

侧载DWG插入带属性块报wrong database错误,求解决思路

问题与解决方案

用户问题

我尝试用以下代码在侧载DWG中插入带属性的块时,在brBlock.AttributeCollection.AppendAttribute(ar);行出现“wrong database”错误。我曾尝试从BlockReference中获取BlockTableRecord但未成功,能否有人指出我操作中的问题?提前感谢。

用户提供的代码

using (Database targetDb = new Database(false, true))
{
    using (Transaction tr = targetDb.TransactionManager.StartTransaction())
    {
        targetDb.ReadDwgFile(file, FileOpenMode.OpenForReadAndAllShare, true, "");
        targetDb.CloseInput(true);

        bool bFixErrors = true;
        bool becho = true;

        ImportAlstomFiles.TransformDwg.InsertTbmBlock(targetDb);

        targetDb.Audit(bFixErrors, becho);
        targetDb.SaveAs(file, DwgVersion.Current);

        tr.Commit();
    }
}

public class TransformDwg
{
    public static void InsertTbm(Database db)
    {

        string[] files = Directory.GetFiles(@"C:\ProgramData\Autodesk\ApplicationPlugins\SpNwDo.bundle\Contents\Block\Alstom\", "*.dwg");


        foreach (string file in files)
        {
            string blockname = Path.GetFileNameWithoutExtension(file);

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                Database tmpDb = new Database(false, true);
                tmpDb.ReadDwgFile(file, FileShare.Read, true, "");

                db.Insert(blockname, tmpDb, true);

                tr.Commit();
            }
        }

        Point3d insPoint = new Point3d();

        using (Transaction tr = db.TransactionManager.StartTransaction())
        {
            // Open BlockTable and BlockTableRecord
            BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
            BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

            // Retrieve the inserted block definition
            BlockTableRecord btrBlock = tr.GetObject(bt["Alstom_TBM_DATA01_S_N"], OpenMode.ForRead) as BlockTableRecord;

            // Loop through the inserted block references and retrieve attribute values
            foreach (ObjectId btrId in btr)
            {
                if (btrId.ObjectClass.DxfName == "INSERT")
                {
                    BlockReference br = tr.GetObject(btrId, OpenMode.ForWrite) as BlockReference;
                    SymbolTableRecord str = tr.GetObject(br.DynamicBlockTableRecord, OpenMode.ForRead) as SymbolTableRecord;



                        using (BlockReference brBlock = new BlockReference(insPoint, btrBlock.ObjectId))
                        {

                            btr.UpgradeOpen();

                            // Append the new BlockReference to PaperSpace
                            btr.AppendEntity(brBlock);
                            tr.AddNewlyCreatedDBObject(brBlock, true);

                            // Loop through BlockTableRecord to create AttributeReferences
                            foreach (ObjectId btrBlockId in btrBlock)
                            {
                                AttributeDefinition ad = tr.GetObject(btrBlockId, OpenMode.ForWrite) as AttributeDefinition;

                                if (ad != null)
                                {
                                    // Create a new AttributeReference in the correct database (db)
                                    using (AttributeReference ar = new AttributeReference())
                                    {
                                        // Set the attribute values and transformation
                                        ar.SetAttributeFromBlock(ad, brBlock.BlockTransform);

                                        // Update the text for each attribute based on collected values
                                        if (ar.Tag == "AT_DATA_ZONE_N")
                                            ar.TextString = zone;
                                        if (ar.Tag == "AT_DATA_STATION_N")
                                            ar.TextString = station;
                                        if (ar.Tag == "AT_DATA_BLOCKNUM_N")
                                            ar.TextString = blocknum;
                                        if (ar.Tag == "AT_DATA_DESC3_S_N")
                                            ar.TextString = lijn1;
                                        if (ar.Tag == "AT_DATA_DESC4_S_N")
                                            ar.TextString = lijn2;
                                        if (ar.Tag == "AT_DATA_DESC5_S_N")
                                            ar.TextString = lijn3;

                                        // Add the AttributeReference to the BlockReference's AttributeCollection
                                        brBlock.AttributeCollection.AppendAttribute(ar);

                                        // Ensure the attribute is added to the transaction
                                        tr.AddNewlyCreatedDBObject(ar, true);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

问题分析与修正

核心错误原因

wrong database错误是因为**AttributeReference对象的数据库上下文与BlockReference(brBlock)不匹配**:你用无参构造函数创建AttributeReference时,它默认不属于目标数据库db,而brBlock是属于db的,两者数据库不一致导致附加属性时报错。

具体问题及修复

  1. 为AttributeReference指定目标数据库
    创建AttributeReference时,必须明确关联到目标数据库db,可以通过重载构造函数实现:

    using (AttributeReference ar = new AttributeReference(db))
    

    或者在创建后设置ar.Database = db;,确保属性对象和块引用属于同一个数据库。

  2. 修改AttributeDefinition的打开模式
    遍历块定义中的属性定义时,仅需读取信息,无需以写模式打开,改成OpenMode.ForRead即可:

    AttributeDefinition ad = tr.GetObject(btrBlockId, OpenMode.ForRead) as AttributeDefinition;
    
  3. 移除冗余的UpgradeOpen调用
    已经将模型空间btr以OpenMode.ForWrite打开,循环内无需重复调用btr.UpgradeOpen();,可以删除该语句。

修正后的关键代码片段

// 遍历块定义中的属性定义
foreach (ObjectId btrBlockId in btrBlock)
{
    AttributeDefinition ad = tr.GetObject(btrBlockId, OpenMode.ForRead) as AttributeDefinition;

    if (ad != null)
    {
        // 创建AttributeReference时指定目标数据库
        using (AttributeReference ar = new AttributeReference(db))
        {
            ar.SetAttributeFromBlock(ad, brBlock.BlockTransform);

            // 设置属性文本
            if (ar.Tag == "AT_DATA_ZONE_N")
                ar.TextString = zone;
            if (ar.Tag == "AT_DATA_STATION_N")
                ar.TextString = station;
            if (ar.Tag == "AT_DATA_BLOCKNUM_N")
                ar.TextString = blocknum;
            if (ar.Tag == "AT_DATA_DESC3_S_N")
                ar.TextString = lijn1;
            if (ar.Tag == "AT_DATA_DESC4_S_N")
                ar.TextString = lijn2;
            if (ar.Tag == "AT_DATA_DESC5_S_N")
                ar.TextString = lijn3;

            brBlock.AttributeCollection.AppendAttribute(ar);
            tr.AddNewlyCreatedDBObject(ar, true);
        }
    }
}

其他潜在问题

  • 代码中zone、station等变量未定义,需确保这些变量已正确赋值。
  • 插入块的循环中,每次创建独立事务并提交可以优化为单个事务处理所有块插入,提升性能。

内容的提问来源于stack exchange,提问作者Pluribus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 19:17:08