So, I have created a class to convert these values into each other, and make it possible to use raw field of oracle in .NET:
public class IDField
{
private Guid OracleGUID { get; set; }
public Guid Value { get; private set; }
private IDField(byte[] gByte, bool isMicrosoftGuid)
{
if (isMicrosoftGuid)
{
Value = new Guid(gByte);
SwapArrayElements(gByte);
OracleGUID = new Guid(gByte);
}
else
{
OracleGUID = new Guid(gByte);
SwapArrayElements(gByte);
Value = new Guid(gByte);
}
}
/Convertion from one to other, doesn't matter which one it is at the moment the function is called
//the elements are not touching each other, so this method can be used both ways
private void SwapArrayElements(byte[] gByte)
{
//Microsoft { 3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15 };
//Oracle { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
//Oracle { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
gByte.Swap(0, 3);
//Oracle { 3, 1, 2, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
gByte.Swap(1, 2);
//Oracle { 3, 2, 1, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
gByte.Swap(4, 5);
//Oracle { 3, 2, 1, 0, 5, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
gByte.Swap(6, 7);
//Oracle { 3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15 };
}
public byte[] ToOracleByteArray()
{
return this.OracleGUID.ToByteArray();
}
public string ToLDAPString()
{
return this.Value.ToString().Replace("-", "");
}
public override string ToString()
{
return this.ToLDAPString();
}
public static IDField CreateFromOracleByteArray(byte[] gByte)
{
IDField id = new IDField(gByte, false);
return id;
}
public static IDField CreateFromMicrosoftByteArray(byte[] gByte)
{
IDField id = new IDField(gByte, true);
return id;
}
public static IDField CreateFromMicrosoftGuid(Guid g)
{
IDField id = new IDField(g.ToByteArray(), true);
return id;
}
public static IDField CreateFromLDAPGuidString(string id)
{
Guid g = ConvertToGuid(id);
if (g.Equals(Guid.Empty))
return null;
else
return IDField.CreateFromMicrosoftGuid(g);
}
private static Guid ConvertToGuid(string s)
{
if (!string.IsNullOrEmpty(s))
{
try
{
//covert to guid
return new Guid(s);
}
catch
{
//not guid
}
}
return Guid.Empty;
}
}
and the extension method:
public static class Extensions
{
public static void Swap(this byte[] array, int i1, int i2)
{
byte temp = array[i1];
array[i1] = array[i2];
array[i2] = temp;
}
}
As you can see, I am also storing this field in LDAP as string.
4 comments:
this was really helpful. i spent 6 hours trying to figure out why the guid coming back from oracle was not in a "proper" format. why do they do this, and who do I blame, microsoft or oracle? thanks for ending my frustration.
Ditto on the above comment.
Except, luckily, I managed to get away with only 4 hours. ;)
Very helpful! I created an Oracle query to calculate the same result if you needed to know the Microsoft GUID representation of the sys_guid() returned Oracle GUID in the database.
select
lower(SubStr(:guid, 7, 1) || SubStr(:guid, 8, 1) || SubStr(:guid, 5, 1) || SubStr(:guid, 6, 1) || SubStr(:guid, 3, 1) || SubStr(:guid, 4, 1) || SubStr(:guid, 1, 1) || SubStr(:guid, 2, 1) || '-' ||
SubStr(:guid, 11, 1) || SubStr(:guid, 12, 1) || SubStr(:guid, 9, 1) || SubStr(:guid, 10, 1) || '-' ||
SubStr(:guid, 15, 1) || SubStr(:guid, 16, 1) || SubStr(:guid, 13, 1) || SubStr(:guid, 14, 1) || '-' ||
SubStr(:guid, 17, 4) || '-' ||
SubStr(:guid, 21, 12))
from dual;
Great!!! Thank you!
I would blame microsoft :)
Post a Comment