llblgen 5.5 (5.5.3) RTM - Adapter - FetchEntityCollection Type Convert Error

Posts   
 
    
sapul
User
Posts: 49
Joined: 11-Jan-2019
# Posted on: 18-Sep-2019 16:34:38   

Hi.

I searched the forum for the related error but did not worked for me. After migrating our project from 2.6 to 5.5.3, we get the error in the following scenario.

We'd really appreciate it if you could help. Regards, Serkan

Repository.cs

protected EntityCollectionBase2<AEntity> GetMulti<AEntity>(IRelationPredicateBucket predicateBucket, int maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath2 prefetchPath) where AEntity : global::SD.LLBLGen.Pro.ORMSupportClasses.EntityBase2, global::SD.LLBLGen.Pro.ORMSupportClasses.IEntity2
        {
            EntityCollection<AEntity> collection = new EntityCollection<AEntity>();
            return (EntityCollectionBase2<AEntity>)FillColl(collection, predicateBucket, maxNumberOfItemsToReturn, sortClauses, prefetchPath);
        }

private IEntityCollection2 FillColl(IEntityCollection2 collection, IRelationPredicateBucket predicateBucket, int maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath2 prefetchPath)
        {
            if (prefetchPath == null)
                prefetchPath = GetPrefetchPath();
            dataAccessAdapter.FetchEntityCollection(collection, predicateBucket, maxNumberOfItemsToReturn, sortClauses, prefetchPath);
            return collection;
        }

System.NullReferenceException occurred

at SD.LLBLGen.Pro.TypeConverters.BooleanNullableNumericConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value) at SD.LLBLGen.Pro.ORMSupportClasses.PersistenceCore.ReadRowIntoFields(Object[] values, IEntityFieldsCore rowDestination, Dictionary2 indicesForEnumConverts, Dictionary2 indicesForTypeConverters, Dictionary2 hierarchyFieldValueArrayLengths, Dictionary2 entityFieldStartIndexesPerEntity) in C:\Myprojects\VS.NET Projects\LLBLGen Pro v5.5\Frameworks\LLBLGen Pro\RuntimeLibraries\ORMSupportClasses\Persistence\PersistenceCore.cs:line 499 at SD.LLBLGen.Pro.ORMSupportClasses.PersistenceCore.CreateEntityInstanceFromReaderRow(IEntityFactoryCore entityFactory, InheritanceHierarchyType typeOfHierarchy, Object[] valuesOfRow, Dictionary2 indicesForEnumConverts, Dictionary2 indicesForTypeConverters, Dictionary2 hierarchyFieldValueArrayLengths, Dictionary2 entityFieldStartIndexesPerEntity, Boolean selfServicing, IEntityFactoryCore& entityFactoryToUse) in C:\Myprojects\VS.NET Projects\LLBLGen Pro v5.5\Frameworks\LLBLGen Pro\RuntimeLibraries\ORMSupportClasses\Persistence\PersistenceCore.cs:line 2458 at SD.LLBLGen.Pro.ORMSupportClasses.EntityMaterializerBase.HandleRowData(Object[] valuesOfRow, FetchCounters counters) in C:\Myprojects\VS.NET Projects\LLBLGen Pro v5.5\Frameworks\LLBLGen Pro\RuntimeLibraries\ORMSupportClasses\Persistence\EntityMaterializerBase.cs:line 302 at SD.LLBLGen.Pro.ORMSupportClasses.EntityMaterializerBase.Materialize(Func4 valueReadErrorHandler, String& failureErrorText) in C:\Myprojects\VS.NET Projects\LLBLGen Pro v5.5\Frameworks\LLBLGen Pro\RuntimeLibraries\ORMSupportClasses\Persistence\EntityMaterializerBase.cs:line 181 at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterCore.ExecuteMultiRowRetrievalQuery(IRetrievalQuery queryToExecute, IEntityFactory2 entityFactory, IEntityCollection2 collectionToFill, IFieldPersistenceInfo[] fieldsPersistenceInfo, Boolean allowDuplicates, IEntityFields2 fieldsUsedForQuery) in C:\Myprojects\VS.NET Projects\LLBLGen Pro v5.5\Frameworks\LLBLGen Pro\RuntimeLibraries\ORMSupportClasses\AdapterSpecific\DataAccessAdapterCore.cs:line 810 at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterCore.FetchEntityCollectionInternal(QueryParameters parameters) in C:\Myprojects\VS.NET Projects\LLBLGen Pro v5.5\Frameworks\LLBLGen Pro\RuntimeLibraries\ORMSupportClasses\AdapterSpecific\DataAccessAdapterCore.cs:line 6422 at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterCore.FetchEntityCollection(QueryParameters parameters) in C:\Myprojects\VS.NET Projects\LLBLGen Pro v5.5\Frameworks\LLBLGen Pro\RuntimeLibraries\ORMSupportClasses\AdapterSpecific\DataAccessAdapterCore.cs:line 2379 at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.<>c__DisplayClass10_0.<FetchEntityCollection>b__0() in C:\Myprojects\VS.NET Projects\LLBLGen Pro v5.5\Frameworks\LLBLGen Pro\RuntimeLibraries\ORMSupportClasses\AdapterSpecific\DataAccessAdapterBase.cs:line 251 at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.ExecuteWithActiveRecoveryStrategy(Action toExecute) in C:\Myprojects\VS.NET Projects\LLBLGen Pro v5.5\Frameworks\LLBLGen Pro\RuntimeLibraries\ORMSupportClasses\AdapterSpecific\DataAccessAdapterBase.cs:line 892 at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntityCollection(QueryParameters parameters) in C:\Myprojects\VS.NET Projects\LLBLGen Pro v5.5\Frameworks\LLBLGen Pro\RuntimeLibraries\ORMSupportClasses\AdapterSpecific\DataAccessAdapterBase.cs:line 251 at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterCore.FetchEntityCollection(IEntityCollection2 collectionToFill, IRelationPredicateBucket filterBucket, Int32 maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath2 prefetchPath, ExcludeIncludeFieldsList excludedIncludedFields, Int32 pageNumber, Int32 pageSize) in C:\Myprojects\VS.NET Projects\LLBLGen Pro v5.5\Frameworks\LLBLGen Pro\RuntimeLibraries\ORMSupportClasses\AdapterSpecific\DataAccessAdapterCore.cs:line 2344 at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterCore.FetchEntityCollection(IEntityCollection2 collectionToFill, IRelationPredicateBucket filterBucket, Int32 maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath2 prefetchPath) in C:\Myprojects\VS.NET Projects\LLBLGen Pro v5.5\Frameworks\LLBLGen Pro\RuntimeLibraries\ORMSupportClasses\AdapterSpecific\DataAccessAdapterCore.cs:line 2247 at Data.Core.Repository1.FillColl(IEntityCollection2 collection, IRelationPredicateBucket predicateBucket, Int32 maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath2 prefetchPath) in C:\VSTS Projeleri\LoopYnl\Infrastructure.Data\Data.Core\Repository.cs:line 174 at Data.Core.Repository1.GetMulti[AEntity](IRelationPredicateBucket predicateBucket, Int32 maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath2 prefetchPath) in C:\VSTS Projeleri\LoopYnl\Infrastructure.Data\Data.Core\Repository.cs:line 284 at Data.Main.YeniBookingModule.YeniBookingRepository.YnBkgEntityListele(YnBkgEntity ynBkgEntity, Nullable1 MusteriId, String KonteynerNo, String SeferNo, String PlakaNo, Nullable1 BaslangicTarihi, Nullable1 BitisTarihi, Nullable1 HizmetId, Int64[] yetkiliOfisleri, Int64[] BookingDurumIds, Nullable1 BaslangicLokasyonId, Nullable1 BitisLokasyonId, Nullable1 PazarlamaciId, Nullable1 OperasyoncuId, String RezervasyonNo, String YukNo, Nullable1 KapanisBaslangicTarihi, Nullable1 KapanisBitisTarihi, Nullable1 GiderMusteriId, Nullable`1 tasimaTedarikciId, YnMalEntity ynMalEntity, Int64[] yetkiliIsTipleri, Boolean TopluBookingGuncellemeMi) in C:\VSTS Projeleri\LoopYnl\Infrastructure.Data\Data.Main\YeniBookingModule\YeniBookingRepository.cs:line 620 at Application.Main.YeniBookingModule.YeniBookingAppService.YnBkgEntityListele(YnBkgEntityListeleRequest request) in C:\VSTS Projeleri\LoopYnl\Application.Main\YeniBooking\YeniBookingAppService.cs:line 2580 at DynamicModule.ns.Wrapped_IYeniBookingAppService_498a96459aaf4335ad8c3c3ca9557e3e.<YnBkgEntityListele_DelegateImplementation>__441(IMethodInvocation inputs, GetNextInterceptionBehaviorDelegate getNext)

Attachments
Filename File size Added on Approval
FetchEntityCollectionError.png 108,038 18-Sep-2019 16:35.02 Approved
burcina
User
Posts: 3
Joined: 18-Sep-2019
# Posted on: 19-Sep-2019 10:21:21   

Hi, You're right. We are sorry that we did not recognise that point. We've updated the typeconverter dll. It appears "external types currently loaded into the system" (pls see image1) but it doesnt listed in the Converter To Use, for the Int15 short types in the "field mappings" window. (please see image2)

i think we misses some point, so still we need help simple_smile

here is the code you ask for

public class BooleanNullableNumericConverter : SystemTypeConverterBase
    {
        protected override bool CheckFromType(Type typeToCheck)
        {
            TypeCode typeCode = Type.GetTypeCode(typeToCheck);
            return typeCode - TypeCode.SByte <= TypeCode.UInt32;
        }
        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            return destinationType == typeof(bool);
        }
        public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
        {
            return true;
        }
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            if (value == null || value == DBNull.Value)
            {
                return value;
            }
            return base.ConvertFrom(context, culture, value);
        }
        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            if (value == null || value == DBNull.Value)
            {
                return value;
            }
            return base.ConvertTo(context, culture, value, destinationType);
        }
    }
Attachments
Filename File size Added on Approval
llblgen_external_types.png 115,956 19-Sep-2019 10:22.22 Approved
burcina
User
Posts: 3
Joined: 18-Sep-2019
# Posted on: 19-Sep-2019 10:22:49   

image2

Attachments
Filename File size Added on Approval
llblgen_fieldsmappins.png 35,649 19-Sep-2019 10:22.55 Approved
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39568
Joined: 17-Aug-2003
# Posted on: 19-Sep-2019 10:24:51   

(removed answer as you posted more info)

Ok, let's take a step back, as this gets confusing fast.

The shipped BooleanNumericConverter is meant to convert any numeric value to boolean. Could you please elaborate why it's not sufficient? As it can convert any numeric value to boolean and back? Or do you need a different numeric value for 'true' ?

Frans Bouma | Lead developer LLBLGen Pro
sapul
User
Posts: 49
Joined: 11-Jan-2019
# Posted on: 19-Sep-2019 10:52:23   

Hi Frans, We want to convert null value of Int16 (1) to -> null (instead of "false")

DB value EntityField (bool?)


1 true ✔ 0 false ✔ null nullfalse

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39568
Joined: 17-Aug-2003
# Posted on: 19-Sep-2019 11:06:56   

The problem is that the converter you've extended is a system converter, these don't do any conversions, they're meant for the designer: when the code is generated the mapped converter present in the target framework is used. As this particular converter doesn't have a mapping (as you defined it yourself), its name is generated as-is. You then added the system converter as type converter, but that's not going to work.

The converter in the runtime framework uses


/// <summary>
/// Performs the ConvertFrom.
/// </summary>
/// <param name="value">The value.</param>
/// <returns>value converted to bool</returns>
/// <remarks>Value is guaranteed to be non-null</remarks>
protected override object PerformConvertFrom(object value)
{
    try
    {
        return Convert.ToBoolean(value, null);
    }
    catch
    {
        throw new NotSupportedException(CreateInvalidConvertFromExceptionMessage(value));
    }
}

Which converts null to false, as Convert.ToBoolean(null, null) returns false.

All DBNull.Value values are already converted to null before type converters are ran, so this is safe.

I think you can safely use the built-in type converter and it should work as expected.

Frans Bouma | Lead developer LLBLGen Pro
sapul
User
Posts: 49
Joined: 11-Jan-2019
# Posted on: 19-Sep-2019 12:57:30   

because we are upgrading an existing project, i need to implement this feature. I mean i need the entity field to be set null value when it is null in the table.

by the way, do you mean what ever i do, this is not possible any more?

All DBNull.Value values are already converted to null before type converters are ran, so this is safe.

i just could not figure out why this refactor does not work (please give attention to the first IF block)

 public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
           if (value == null || value == DBNull.Value)
            {
                return value;
            }
            return base.ConvertFrom(context, culture, value);
        }

Changing the PerformConvertFrom method with same way, does not help?

is there anything i can do to overcome this issue?

sapul
User
Posts: 49
Joined: 11-Jan-2019
# Posted on: 19-Sep-2019 15:27:05   

we're implementing a custom conventer. let us see if it works ...

https://www.llblgen.com/Documentation/5.5/SDK/gui_implementingtypeconverter.htm

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39568
Joined: 17-Aug-2003
# Posted on: 19-Sep-2019 15:30:10   

sapul wrote:

because we are upgrading an existing project, i need to implement this feature. I mean i need the entity field to be set null value when it is null in the table.

Oh of course, my mistake flushed

by the way, do you mean what ever i do, this is not possible any more?

All DBNull.Value values are already converted to null before type converters are ran, so this is safe.

Yes it is possible simple_smile In v2.x DBNull.value was passed to the type converter in some situations. (so you had to convert yourself). It's now always null, never DBNull.Value

i just could not figure out why this refactor does not work (please give attention to the first IF block)

 public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
           if (value == null || value == DBNull.Value)
            {
                return value;
            }
            return base.ConvertFrom(context, culture, value);
        }

Changing the PerformConvertFrom method with same way, does not help?

is there anything i can do to overcome this issue?

Because you derived from a class that's not meant to be used at runtime.

We have the class you want in source in the SDK: https://www.llblgen.com/Documentation/5.6/SDK/gui_implementingtypeconverter.htm#llblgen-pro-runtime-framework-version

So if you copy that class code and store it in a dll separately from ours, you also don't run the risk that you overwrite it when you install an upgrade. You currently store the typeconverter in our system type converters dll which isn't recommended: the type converters there are only meant for modeling, not for runtime usage, and a new designer version might overwrite that dll.

To make it return null if the value is null, you have to add a test to ConvertFrom and return null if the value is null. that's it.

Frans Bouma | Lead developer LLBLGen Pro
burcina
User
Posts: 3
Joined: 18-Sep-2019
# Posted on: 19-Sep-2019 16:53:21   

As you mentioned, we proceeded and solved our problem. Thank you for your attention.