LINQ and the AutoCAD .NET API (Part 6)
Write operations
This is the sixth in a series of posts on LINQ an the AutoCAD .NET API. Here's a complete list of posts in this series.
Introduction
This is part 6 of our series on LINQ and the AutoCAD .NET API. Currently the GeneralHelper
class only support read operations. If we perform a write operation on one of the objects we pulled out of the database, we get an exception. In this blog post we want to correct this behaviour.
UpgradeOpen()
On the level of a single database object, the DBObject
class provides two methods that let us change the open mode of a DBObject
: UpgradeOpen()
makes a DBObject
writable, DowngradeOpen()
makes it read only. Since the for-read-mode is currently our default mode, we first look at how to find a procedure to open a collection of DBObjects
for for-write.
Collections
When we use the GeneralHelper
class, which collections are we dealing with? Well, the access properties of the GeneralHelper
class are of type IEnumerable<T>
, where T
is derived from DBObject
. Since every .NET collection implements IEnumerable<T>
, we could define an extension method for IEnumerable<T>
and restrict T
to DBObject
. In other words: whenever a .NET container class contains items that are derived from DBOBject
, our extension method to make items for-write would become available. Let's look at the implementation:
The implementation of ForWrite
is straightforward: we iterate the source items, which are DBObjects
due to the type constraint, and upgrade each item, in case it is not yet write-enabled. The ForEach
method is just for convenience, to easily iterate elements of an enumerable of DBObjects
.
Now as an example, to delete all lines and circles from the model space, we now can do the following:
As we can see, the ForWrite
method is not tied to any of our GeneralHelper
methods or properties, but also works perfectly fine with a list of Circles (line 20).
For the sake of completeness, we can add a ForRead
extension method as well:
Commit()
If we run the example in listing 2, we don't get any error, because the objects are in the correct state: we want to make changes to the objects and their state is changed to for-write via the call to ForWrite()
. But in the transaction based world of AutoCAD objects, opening objects for-write is only the first step. To make any changes persistend, we finally have to commit the transaction.
So for starters, it would be OK to commit the transaction at the latest possible moment, that is, just right before the transaction is disposed. So we simply add the commit to the Dispose
method of the GeneralHelper
class:
With this change, the example in listing 2 works perfectly fine and the changes are persisted in the database.
What's next
By now we've come pretty far. The GeneralHelper
class now supports read and write operations in a convenient way. In the next post we will have a look at how to improve the creation of objects and we will do some refactoring. Stay tuned.