.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Empty blocktablerecord when inserting from and to database

1 REPLY 1
Reply
Message 1 of 2
vinkd
286 Views, 1 Reply

Empty blocktablerecord when inserting from and to database

I've recently been porting a batch processing application to work directly on the database instead of the Document so all processing can be done in the background.

 

As a part of this port I rewrote my generic block insert snippet to cope with just a database instead of a document and added 'forwarding methods' to maintain backwards compatibility:

 

Spoiler

 

        public static ObjectId insertBlock(Document acDoc, Transaction acTrans, string blocknaam, DefaultBlock defBlock = DefaultBlock.None)
        {
            return InsertBlock(acDoc, acTrans, blocknaam, false, defBlock);
        }

        public static ObjectId InsertBlock(Document acDoc, Transaction acTrans, string blocknaam, bool overrideExisting = false, DefaultBlock defBlock = DefaultBlock.None)
        {
            return InsertBlock(acDoc.Database, acTrans, blocknaam, overrideExisting, defBlock);
        }
        public static ObjectId InsertBlock(Database db, Transaction acTrans, string blockName, bool overrideExisting = false, DefaultBlock defBlock = DefaultBlock.None)
        {
            ObjectId blkid = ObjectId.Null;
            BlockTable blktbl = acTrans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;

            if ((blockName != BlockTableRecord.ModelSpace) && (!blktbl.Has(blockName) || overrideExisting)) {
                string fileName = null;
                //Insert the block
                try {
                    fileName = HostApplicationServices.Current.FindFile(blockName + ".dwg", db, FindFileHint.Default);
                }
                catch {
                    //Block hasn't been found. For now just return ObjectId.Null
                    //return CreateBlock(db, acTrans, defBlock);
                    return ObjectId.Null;
                }
                if (!string.IsNullOrEmpty(fileName)) {
                    Database dbNew = new Database(false, false);
                    dbNew.ReadDwgFile(fileName, System.IO.FileShare.Read, false, null);
                    blkid = db.Insert(blockName, db, false);
                    dbNew.Dispose();
                }
            }
            else {
                blkid = blktbl[blockName];
            }
            return blkid;
        }
    }
    internal enum DefaultBlock
    {
        None = -1,
        Point = 0,
        Cross = 1,
        Circle = 2,
    }

 

 

 

The old main block was as following (apologies for the few dutch terms)

 

 

Spoiler

 

		public static ObjectId insertBlock(Document acDoc, Transaction acTrans, string blocknaam, DefaultBlock defBlock = DefaultBlock.None)
		{
			ObjectId blkid = ObjectId.Null;
			BlockTable blktbl = acTrans.GetObject(acDoc.Database.BlockTableId, OpenMode.ForRead) as BlockTable;

			if ((blocknaam != BlockTableRecord.ModelSpace) && (!blktbl.Has(blocknaam))) {
				string fileName = null;
				//We moeten inserten
				try {
					fileName = HostApplicationServices.Current.FindFile(blocknaam + ".dwg", acDoc.Database, FindFileHint.Default);
#if DEBUG
                    acDoc.Editor.WriteMessage("\nBlock {0} inserted from {1}", blocknaam, fileName);
#endif
				}
				catch {
					//Block niet gevonden. Afhankelijk van instellingen moeten we 'm gaan maken
					return CreateBlock(acDoc, acTrans, defBlock, blocknaam);
				}
				if (!string.IsNullOrEmpty(fileName)) {
					Database db = new Database(false, false);
					db.ReadDwgFile(fileName, System.IO.FileShare.Read, false, null);
					blkid = acDoc.Database.Insert(blocknaam, db, false);
					db.Dispose();
				}
			}
			else {
				blkid = blktbl[blocknaam];
			}
			return blkid;
		}

 

 

 

The old code worked, and stills works, just fine. The new code however returns a valid ObjectId for the BlockTableRecord, but when a block with this blkid is inserted, the block is empty. When edited with the block editor, the BlockTableRecord seems to be empty too.

 

The bug seems to be in the following code:

        public static ObjectId InsertBlock(Database db, Transaction acTrans, string blockName, bool overrideExisting = false, DefaultBlock defBlock = DefaultBlock.None)
        {
            if (!string.IsNullOrEmpty(fileName)) {
                Database dbNew = new Database(false, false);
                dbNew.ReadDwgFile(fileName, System.IO.FileShare.Read, false, null);
                blkid = db.Insert(blockName, db, false);
                dbNew.Dispose();
            }
        }

  

Any ideas on how to solve this?

1 REPLY 1
Message 2 of 2
_gile
in reply to: vinkd

Hi,

 

This works for me:

 

        public ObjectId ImportBlock(Database targetDb, string fileName, string blockName, bool overrideExisting)
        {
            if (targetDb == null)
                throw new ArgumentNullException("targetDb");

            if (string.IsNullOrEmpty(fileName))
                throw new ArgumentNullException("fileName");

            if (!File.Exists(fileName))
                throw new FileNotFoundException("File not found", fileName);

            using (Transaction tr = targetDb.TransactionManager.StartOpenCloseTransaction())
            {
                BlockTable bt = (BlockTable)tr.GetObject(targetDb.BlockTableId, OpenMode.ForRead);
                if (bt.Has(blockName) && !overrideExisting)
                    return bt[blockName];
            }

            using (Database sourceDb = new Database())
            {
                sourceDb.ReadDwgFile(fileName, FileShare.Read, false, null);
                return targetDb.Insert(blockName, sourceDb, true);
            }
        }

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost