Inheritance discriminator is case sensitive

Posts   
 
    
TazMizZaz
User
Posts: 34
Joined: 29-Apr-2009
# Posted on: 02-Dec-2016 23:17:34   

I have an issue where I am getting back an exception that a particular discriminator value is unknown. In checking into it, I have discovered that we have "F" defined as the discriminator but this particular row contains "f".

I don't really have control over the data in the database and too much else in the system is case insensitive so I won't easily win a battle about forcing everything to be "F". Is there a setting to be able to ensure the generated code uses a case insensitive search?

LLBLGen 4.1

Stack trace for reference (and for future search ability) (sorry partially JSON formatted due to our logging system):

SD.LLBLGen.Pro.ORMSupportClasses.ORMInheritanceInfoException: Unknown discriminator value 'f' in row read from db, which doesn't exist in hierarchy of root 'FailureProblemSolutionEntity'.\r\n at SD.LLBLGen.Pro.ORMSupportClasses.InheritanceInfoProviderBase.GetEntityFactoryTargetPerEntityHierarchy(String entityName, Object[] values) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v4.2\Frameworks\LLBLGen Pro\RuntimeLibraries\ORMSupportClasses\InfoProviders\InheritanceInfoProviderBase.cs:line 1235\r\n at MaintenanceConnection.API.DataAccess.EntityDB.FactoryClasses.EntityFactoryBase21.GetEntityFactory(Object[] fieldValues, Dictionary2 entityFieldStartIndexesPerEntity) in e:\\Programming\\_gitLab_MCe\\mcEverywhere.v5\\5.31FPS\\MCC_API_EntityDB\\DatabaseGeneric\\FactoryClasses\\EntityFactories.cs:line 70\r\n at SD.LLBLGen.Pro.ORMSupportClasses.PersistenceCore.CreateEntityInstanceFromReaderRow(IEntityFactoryCore entityFactory, InheritanceHierarchyType typeOfHierarchy, Object[] valuesOfRow, UniqueList1 stringCacheForFetcher, Dictionary2 indicesForEnumConverts, Dictionary2 indicesForTypeConverters, List1 indicesForStringInterning, Dictionary2 hierarchyFieldValueArrayLengths, Dictionary2 entityFieldStartIndexesPerEntity, Boolean selfServicing, IEntityFactoryCore& entityFactoryToUse) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v4.2\Frameworks\LLBLGen Pro\RuntimeLibraries\ORMSupportClasses\Persistence\PersistenceCore.cs:line 2300\r\n at SD.LLBLGen.Pro.ORMSupportClasses.EntityMaterializerBase.HandleRowData(Object[] valuesOfRow, FetchCounters counters) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v4.2\Frameworks\LLBLGen Pro\RuntimeLibraries\ORMSupportClasses\Persistence\EntityMaterializerBase.cs:line 243\r\n at SD.LLBLGen.Pro.ORMSupportClasses.EntityMaterializerBase.Materialize(Func`4 valueReadErrorHandler, String& failureErrorText) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v4.2\Frameworks\LLBLGen Pro\RuntimeLibraries\ORMSupportClasses\Persistence\EntityMaterializerBase.cs:line 185\r\n 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 v4.2\Frameworks\LLBLGen Pro\RuntimeLibraries\ORMSupportClasses\AdapterSpecific\DataAccessAdapterCore.cs:line 596\r\n at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterCore.FetchEntityCollectionInternal(QueryParameters parameters) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v4.2\Frameworks\LLBLGen Pro\RuntimeLibraries\ORMSupportClasses\AdapterSpecific\DataAccessAdapterCore.cs:line 4320\r\n at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterCore.FetchEntityCollection(QueryParameters parameters) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v4.2\Frameworks\LLBLGen Pro\RuntimeLibraries\ORMSupportClasses\AdapterSpecific\DataAccessAdapterCore.cs:line 2195\r\n at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.<>c__DisplayClasscf.<FetchEntityCollection>b__ce() in c:\Myprojects\VS.NET Projects\LLBLGen Pro v4.2\Frameworks\LLBLGen Pro\RuntimeLibraries\ORMSupportClasses\AdapterSpecific\DataAccessAdapterBase.cs:line 178\r\n at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProvider2.ExecuteEntityProjection(QueryExpression toExecute) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v4.2\Frameworks\LLBLGen Pro\RuntimeLibraries\ORMSupportClasses\Linq\LLBLGenProProvider2.cs:line 98\r\n at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.ExecuteExpression(Expression handledExpression, Type typeForPostProcessing) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v4.2\Frameworks\LLBLGen Pro\RuntimeLibraries\ORMSupportClasses\Linq\LLBLGenProProviderBase.cs:line 300\r\n at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.System.Linq.IQueryProvider.Execute[TResult](Expression expression) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v4.2\Frameworks\LLBLGen Pro\RuntimeLibraries\ORMSupportClasses\Linq\LLBLGenProProviderBase.cs:line 775

[trimmed off application specific details]

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 05-Dec-2016 07:14:33   

The framework does a...

infoRoot.DiscriminatorValueToTypeName.ContainsKey(discriminatorValue))

to find the factory it has to create based on the discriminator value provided by your model. In this case "F" for some subtype.

As the real problem is in the data before the entity is created/materilized, there are no place where you can hook in and change it. Despite you have no control over the data, it's recommended that this kind of issues would be fixed in the DB directly.

Said that, a couple of possible workarounds:

A. Create another subtype for this specific case. This is not ideal, but it would cover the exception and you can manage the way to want to use this specific type.

B. Modify the way the framework find the entity, so it could be case-insensitive. For this you would have to download the ORMSupportClasses source code and make little adjustments, then use this custom ORMSupportClasses assembly in all your projects.

I would go trying to fix the data first. If that is not possible, think in A. Going through B is not recommended, only if truly necessary.

David Elizondo | LLBLGen Support Team
TazMizZaz
User
Posts: 34
Joined: 29-Apr-2009
# Posted on: 05-Dec-2016 15:12:26   

Unfortunately A is not viable because we have dozens of discriminators and most are not a single character. Creating every possible combination is not reasonable (one table has 7 discriminators which are all 3-7 characters long).

And we really don't have control. This has to work at over 1000 different sites across 10,000 different databases. The database is case insensitive so this MUST just work since it already does in the thousands of places code already exists that doesn't use LLBLGen.

I don't like A, and truly have no ability to fix data that is by definition not broken (as noted anywhere LLBLGen is not used it is working).

I don't like B but it is sounding like that is the only available option to fix this.

Is this something that is or could be fixed in LLBL v5.x?

Since this is currently only happening in one site I am lucky enough to be afforded some time to research and produce a real fix.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 06-Dec-2016 13:52:50   

Case insensitive comparisons aren't going to fly, as it very well may be a duplicate is created somewhere. There's is thus also not such a setting available.

However there's a way: a typeconverter simple_smile Create a typeconverter which converts from string to string and simply uppercases the value in the convertfrom and convertto. Assign it to the discriminator field's field mapping and saving and loading the entity will now run the value first through the typeconverter. This will make sure the value is always uppercased when it's placed inside the entity and thus all checks for types etc. should work OK.

Frans Bouma | Lead developer LLBLGen Pro