Following this initial thread I'm having some problems implementing what was suggested here:
Can I Store An ArcObject inside a BLOB?
Well, following the link Kirk provided, I've came up with this:
public static object GetBlobValue(this IActiveRecord wrapper,FieldAttribute attribute)
{
IMemoryBlobStream blobStream = wrapper.UnderlyingObject.get_Value(attribute.Index) as IMemoryBlobStream;
IPersistStream blob = new PropertySetClass();
blob.Load(blobStream);
return blob as IPropertySet;
}
public static void SetBlobValue(this IActiveRecord wrapper,FieldAttribute attribute,object value)
{
if (!(value is IPersistStream))
throw new ActiveRecordException("Nâo é possível persistir um objeto que não implementa IPersistStream.");
IPropertySet property = new PropertySetClass();
property.SetProperty(attribute.FieldName, value);
IMemoryBlobStream memStream = new MemoryBlobStreamClass();
IPersistStream persist = (IPersistStream)property;
persist.Save(memStream, 0);
wrapper.UnderlyingObject.set_Value(attribute.Index, memStream);
}
Looks like the SetValue code is working. I can see the values in Oracle just fine. But the GetValue method always returns an empty IPropertySet.
I've decided to always wrap an object within the IPropertySet as recommended. I'm not sure what I might be doing wrong, since ESRIs documentation on this is sparse not very detailed.
I've followed tons of examples (tried using IObjectStream, setting IObjectStream.Stream property with IMemoryBlobStream as described here) but no luck. Always an empty IPropertySet. Oh, also I've should mention that I'm trying to persist another IPropertySet to this field - could that be the problem?
Thanks!
-
1What are you putting in the propertyset? If they aren't value types, they'll need to implement IPersistStream (or IPersistVariant) in order to be saved.Kirk Kuykendall– Kirk Kuykendall2011年07月02日 13:22:29 +00:00Commented Jul 2, 2011 at 13:22
-
Just strings and ints for testing purposes.George Silva– George Silva2011年07月06日 19:03:31 +00:00Commented Jul 6, 2011 at 19:03
2 Answers 2
I'm porting an arcmap extension from 9.3.1 to 10.0 (SP2) and just ran into a strange bug (or feature?).
This code worked at 9.3.1 but fails at 10.0 SP2 (no error, I just get an empty propertyset):
public static IPropertySet GetPropset(IRow row, string fldName)
{
int idx = row.Fields.FindField(fldName);
if (idx == -1)
throw new Exception("field not found: " + fldName);
IMemoryBlobStream mbs = row.get_Value(idx) as IMemoryBlobStream;
IPersistStream ps = new PropertySetClass();
ps.Load(mbs);
return (IPropertySet)ps;
}
Here's the workaround for 10.0 (anyone know a more graceful way?)
public static IPropertySet GetPropset(IRow row, string fldName)
{
int idx = row.Fields.FindField(fldName);
if (idx == -1)
throw new Exception("field not found: " + fldName);
IMemoryBlobStream mbs = row.get_Value(idx) as IMemoryBlobStream;
// hack, maybe this could be done gracefully with remoteseek?
object o;
((IMemoryBlobStreamVariant)mbs).ExportToVariant(out o);
var mbs2 = new MemoryBlobStreamClass() as IMemoryBlobStream;
((IMemoryBlobStreamVariant)mbs2).ImportFromVariant(o);
IPersistStream ps = new PropertySetClass();
ps.Load(mbs2);
return (IPropertySet)ps;
}
-
Nice Kirk. I'll try it out. This is hauting me for weeks! What type of storage? if sde, what database?George Silva– George Silva2011年07月12日 11:39:52 +00:00Commented Jul 12, 2011 at 11:39
-
This is with file gdb, but I can also reproduce the bug simply by serializing a propertyset to a memoryblobstream then attempting to deserialize, without ever storing the stream.Kirk Kuykendall– Kirk Kuykendall2011年07月12日 14:01:58 +00:00Commented Jul 12, 2011 at 14:01
-
Thanks @Kirk. This helped me with an issue of getting an empty value when reading the
IMemoryBlobStream2
value into aStrArray
on the second read. I also noticed thatIMemoryBlobStream2
typed fields are handled differently when using recycling cursors. Even when all other values read correctly, theIMemoryBlobStream2
field is some how the only one where the last value read is used for all records returned.Tim Sexton– Tim Sexton2016年11月28日 16:19:43 +00:00Commented Nov 28, 2016 at 16:19
This sample is really old and in VB6 but it shows how to work with the ObjectStream, MemoryBlobStream, and a persistable object: http://edndoc.esri.com/arcobjects/8.3/samples/arcmap/layers/databaselayers/databaselayers.htm