using ExpressionToApply on a field with TypeConverter

Posts   
 
    
virginia
User
Posts: 24
Joined: 29-Nov-2016
# Posted on: 29-Nov-2016 13:09:31   

Hello.

I'm using LLBL v5.0.7 and .net 4.5, connecting to a sql server 2005 database. There's a number(18,0) field in the database that is by default seen by the designer as a decimal and (since we're migrating existing code from v1!!!!! ) it must be Int64, so I'm using a type converter from decimal to int64 on this field. It works ok until I use it in a function returning varchar like this

ResultsetFields m_fields = new ResultsetFields(64);
[...]
m_fields.DefineField(ARBOFields.ARB_ID, 56, "LIBANCETRES");
m_fields[56].ExpressionToApply = new ASTechDBFunctionCall("F_GETLIBANCETRES", new object[] {  ARBOFields.ARB_ID });
[...]


myDataAdapter.FetchTypedList((IEntityFields2)m_fields, dataTableToFill, filterBucket, maxNumberOfItemsToReturn, sortClauses, allowDuplicates, groupByClause, pageNumber, pageSize);

I have an error in my TypeConverter

{"Input string was not in a correct format."}

at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal) at System.Number.ParseDecimal(String value, NumberStyles options, NumberFormatInfo numfmt) at System.Convert.ToDecimal(String value, IFormatProvider provider) at System.String.System.IConvertible.ToDecimal(IFormatProvider provider) at System.Convert.ToDecimal(Object value) at SD.LLBLGen.Pro.TypeConverters.ASTechInt64Converter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)

the value received is "test", the result of my F_GETLIBANCETRES

CREATE FUNCTION F_GETLIBANCETRES (
    @IDBIEN NUMERIC(18)
)
    RETURNS Varchar(2000)
AS
BEGIN

    return 'test'
END

context is null and culture=en-US

The method in the type converter:

 public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
        

            if (value == null || value == System.DBNull.Value) return (System.Int64)0;

            try
            {

                System.Decimal valueTemp = Convert.ToDecimal(value);
                return Decimal.ToInt64(valueTemp);
            }
            catch
            {
                if (value.GetType().FullName.Equals("System.DBNull")||value.ToString().Length==0)
                    return (long)0;

                string err = "Conversion from a value of type '{0}' to System.Decimal isn't supported";
                throw new NotSupportedException(String.Format(err, value.GetType().ToString()));
            }
        }

I assumed the field would take the type of the function, but apparently the data type doesn't change and the type converter is still called, and I can't change the DataType on the field. Does anyone have any solution which does not involve a massive refactoring of the code, which is what not using the type converter implies? I can't believe I'm the only one who ran into this smile Thanks

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 29-Nov-2016 18:58:27   

It's using the Type of the field you defined. As a simple resolution, pic any other String type to define the resultSetField.

m_fields.DefineField(ARBOFields.Use_Any_String_Field,   56, "LIBANCETRES");
m_fields[56].ExpressionToApply = new ASTechDBFunctionCall("F_GETLIBANCETRES", new object[] { ARBOFields.ARB_ID });
virginia
User
Posts: 24
Joined: 29-Nov-2016
# Posted on: 05-Dec-2016 10:00:25   

Thanks, that's what I will do. Still, it seems a bit odd - what if I don't have a string column, what if the function returns a type I don't have in the database? In theory it is possible smile

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 05-Dec-2016 12:15:03   

As the field is used for holding the expression (the field itself isn't used, the expression is), you can also use this:

m_fields[56] = new EntityField2("LIBANCETRES", new ASTechDBFunctionCall("F_GETLIBANCETRES", new object[] { ARBOFields.ARB_ID }), typeof(string));

And you can skip DefineField for that index. The api above was introduced in v2 to help with expressions. simple_smile

Frans Bouma | Lead developer LLBLGen Pro