DbFunctionCall and GetScalar

Posts   
 
    
Kazak1
User
Posts: 39
Joined: 30-May-2006
# Posted on: 17-Jul-2006 18:03:24   

The following code works fine


ResultsetFields fields = new ResultsetFields(1);
fields[0] = new EntityField2("UpperCaseString", new DbFunctionCall("UPPER", new object[] {"test string"}));

using (DataAccessAdapter adapter = new DataAccessAdapter())
{
    DataTable table = new DataTable();
    adapter.FetchTypedList(fields, table, null);
    object result = table.Rows[0]["UpperCaseString"];
}

Why does it fail when I'm trying to use GetScalar instead?


ResultsetFields fields = new ResultsetFields(1);
fields[0] = new EntityField2("UpperCaseString", new DbFunctionCall("UPPER", new object[] { "test string" }));

using (DataAccessAdapter adapter = new DataAccessAdapter())
{
    object result = adapter.GetScalar(new EntityField2("UpperCaseString", new DbFunctionCall("UPPER", new object[] {"test string"})), AggregateFunction.None);
}

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 17-Jul-2006 18:08:19   

how does it fail? What error did you get?

Frans Bouma | Lead developer LLBLGen Pro
Kazak1
User
Posts: 39
Joined: 30-May-2006
# Posted on: 17-Jul-2006 18:21:11   

System.NullReferenceException was unhandled Message="Object reference not set to an instance of an object." Source="SD.LLBLGen.Pro.DQE.Oracle10g.NET20" StackTrace: at SD.LLBLGen.Pro.DQE.Oracle.OracleSpecificCreator.CreateObjectName(IFieldPersistenceInfo persistenceInfo) at SD.LLBLGen.Pro.DQE.Oracle.OracleSpecificCreator.CreateFieldName(IFieldPersistenceInfo persistenceInfo, String fieldName, String objectAlias, Boolean appendAlias, String containingObjectName) at SD.LLBLGen.Pro.ORMSupportClasses.DbSpecificCreatorBase.ConvertFieldToRawName(IEntityFieldCore fieldCore, IFieldPersistenceInfo persistenceInfo, String fieldName, String objectAlias, Int32& uniqueMarker, Boolean applyAggregateFunction) at SD.LLBLGen.Pro.DQE.Oracle.OracleSpecificCreator.CreateFieldName(IEntityFieldCore fieldCore, IFieldPersistenceInfo persistenceInfo, String fieldName, String objectAlias, Int32& uniqueMarker, Boolean applyAggregateFunction) at SD.LLBLGen.Pro.DQE.Oracle.DynamicQueryEngine.CreateSelectDQ(IEntityFieldCore[] selectList, IFieldPersistenceInfo[] fieldsPersistenceInfo, IDbConnection connectionToUse, IPredicate selectFilter, Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relationsToWalk, Boolean allowDuplicates, IGroupByCollection groupByClause, Boolean relationsSpecified, Boolean sortClausesSpecified)

...

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 17-Jul-2006 19:42:40   

Could you try the runtime libraries of 13-jul or later? A change in the runtimes was made to make scalar queries with function calls possible. You can check the version of your runtimes by rightclicking the ormsupportclasses dll -> properties -> version tab.

Frans Bouma | Lead developer LLBLGen Pro
Kazak1
User
Posts: 39
Joined: 30-May-2006
# Posted on: 18-Jul-2006 19:33:24   

I installed the latest July 17th build. It still does not work.

Posts: 1255
Joined: 10-Mar-2006
# Posted on: 18-Jul-2006 20:04:34   

Kazak1, When you get this working, you might want to check out (and consider modifying for Adapter pattern) add-on to help with these functions. Should be easy - I think the only difference will be in the GetScaler function helper - and I imagine you would just remove it in Adapter pattern...

http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=6953

Wayne

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 18-Jul-2006 21:02:49   

Kazak1 wrote:

I installed the latest July 17th build. It still does not work.

Hmm. I'll check it out. Perhaps a small bug still left in the code for oracle, triggered in the scalar specific situation.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 19-Jul-2006 13:04:52   

reproduced.

(edit): A bug in the GetScalar code. This error pops up as the usage of the GetScalar method would force you to use the overload with the expression parameter otherwise, but with the new field constructor which accepts an expression, this is no longer necessary.

What happens is that because you don't specify an expression 'null' is specified to the overload which is called to do the actual getscalar. As null is specified, it will be set as the expression to use on the field. Of course, this overwrites the dbfunctioncall.

It should only set the expression on the field in the getscalar if it's not yet set OR if the expression to set is not null. Will fix this in the next build.

You can work around this by using:


[Test]
public void ScalarQueryWithoutTableReferenceTest()
{
    ResultsetFields fields = new ResultsetFields(1);
    fields[0] = new EntityField2("UpperCaseString", new DbFunctionCall("UPPER", new object[] { "test string" }));

    string toConvert = "test string";
    string result = string.Empty;
    using(DataAccessAdapter adapter = new DataAccessAdapter())
    {
        result = (string)adapter.GetScalar(new EntityField2("UpperCaseString", null), new DbFunctionCall("UPPER", new object[] { toConvert }), AggregateFunction.None);
    }
    Assert.AreEqual(toConvert.ToUpperInvariant(), result);
}

instead, so specify the db call as the expression to apply on the field specified.

Frans Bouma | Lead developer LLBLGen Pro