4

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!

  • 1
    What 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 Jul 2 '11 at 13:22
  • Just strings and ints for testing purposes. – George Silva Jul 6 '11 at 19:03
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 Jul 12 '11 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 Jul 12 '11 at 14:01
  • Thanks @Kirk. This helped me with an issue of getting an empty value when reading the IMemoryBlobStream2 value into a StrArray on the second read. I also noticed that IMemoryBlobStream2 typed fields are handled differently when using recycling cursors. Even when all other values read correctly, the IMemoryBlobStream2field is some how the only one where the last value read is used for all records returned. – Tim Sexton Nov 28 '16 at 16:19
0

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.