- edited description
Invalid variant type conversion
Hi Linas, I am having issues mapping a MS SQL VarBinary Field to a String in a test App. Below is my PODO.
type
[Entity]
[Table('META_USERS')]
TUser = class
private
[Column('USERID', [cpRequired, cpPrimaryKey, cpNotNull, cpDontInsert])]
[AutoGenerated]
FUserID : Int32;
[Column('LOGIN_NAME', [])]
FLoginName : string;
[Column('FULL_NAME', [])]
FFullName : string;
[Column('PASSWORD', [])]
FPassword : string;
public
property UserID : Int32 read FUserID write FUserID;
property LoginName : string read FLoginName write FLoginName;
property FullName : string read FFullName write FFullname ;
property Password : string read FPassword write FPassword;
end;
A DAO
TUserDBO = class
FDBSession : TSession;
public
constructor Create;
destructor destroy;overload;
function GetAllUsers : IList<TUser>;
end;
implementation
uses
MetaADOConnectionUtils;
constructor TUserDBO.Create;
begin
FDBSession := TDBConnection.GetInstance.CreateDBSessionManager;
end;
destructor TUserDBO.destroy;
begin
FDBSession.Connection.Disconnect;
FDBSession.Free;
FDBSession := nil;
inherited;
end;
function TUserDBO.GetAllUsers : IList<TUser>;
begin
Result := FDBSession.FindAll<TUser>;
end;
and the call code on a form
var
AllUsers : IList<TUser>;
dao : TUserDBO;
aUser : TUser;
begin
dao := TUserDBO.Create;
AllUsers := dao.GetAllUsers;
Memo5.Lines.Clear;
for aUser in AllUsers do
Memo5.Lines.Add(aUser.LoginName)
The above codes raises above error but works all right if the Password Mapping which is a varbinary is commented out.
Comments (6)
-
repo owner -
repo owner Where does the exception come from? From Spring.TValueHelper.FromVariant? If so then the varbinary to string conversion needs to be added. I just don't know what the vartype of a varbinary field is from the top of my head.
-
repo owner -
assigned issue to
- changed milestone to 1.2
- removed version
-
assigned issue to
-
repo owner - changed status to open
-
repo owner The ORM does not convert varbinary (which is internally treated as TArray<Byte>) to string by itself.
However using the TValueConverters you can register a converter that handles this. I recommend not using TArray<Byte> to string conversion but use a new string type for your password field to it only handles this explicit type.
type VarBinaryPasswordString = type string; [Table('TEST')] TTest = class [Column([cpPrimaryKey])] Id: Integer; [Column] Password: VarBinaryPasswordString; end;
Then define the converter and register it:
uses Spring.ValueConverters; type TByteArrayToStringConverter = class(TValueConverter) protected function DoConvertTo(const value: TValue; const targetTypeInfo: PTypeInfo; const parameter: TValue): TValue; override; end; function TByteArrayToStringConverter.DoConvertTo(const value: TValue; const targetTypeInfo: PTypeInfo; const parameter: TValue): TValue; begin Result := TEncoding.Unicode.GetString(value.AsType<TArray<Byte>>); // or another encoding depending on how the string is saved in the database end; TValueConverterFactory.RegisterConverter(TypeInfo(TArray<Byte>), TypeInfo(VarBinaryPasswordString), TByteArrayToStringConverter);
You also need the other way around if you want to save the value. This is currently broken and I am fixing this.
-
repo owner - changed status to resolved
refactoring of TDBParam (fixed issue
#119)→ <<cset 19adefb97421>>
- Log in to comment