Paging and Aggregates on typed list

Posts   
 
    
John
User
Posts: 28
Joined: 15-Jan-2005
# Posted on: 24-Feb-2005 20:00:32   

Sorry to be a pain and I appologise for my lack of correct jargon and understanding.

I am having problems applying an aggregate function with paging, on a typed list that I also want to apply an aggregate function to?

The problem is that the typed list (tlServicesSummary) is being returned OK in that there are the correct number of records being returned (52), I can tell this by manaually paging changing the querystring and paging through results

However the RecordCount function is not returning the correct number of rows, it keeps coming back with only 2?

I cant see where to go next?

Many thanks



// Get ServicesSummaryTypedList & adapter
tlServicesSummary = new ServicesSummaryTypedList();
DataAccessAdapter adapter = new DataAccessAdapter();

// Filters
IRelationPredicateBucket filter = tlServicesSummary.GetRelationInfo();
// ServiceCategory
if(KeyServiceCategory != 0)
    filter.PredicateExpression.Add(PredicateFactory.CompareValue(SerServicesFieldIndex.KeyFserviceCategory, ComparisonOperator.Equal, KeyServiceCategory));

// Sort by ServiceName
ISortExpression sorter = new SortExpression(SortClauseFactory.Create(SerServicesFieldIndex.ServiceName, SortOperator.Ascending));

// Get fields and apply SUM(KeyFserviceContent) & GROUP BY
ResultsetFields fields = (ResultsetFields) tlServicesSummary.GetFieldsInfo();

fields["KeyFserviceContent"].AggregateFunctionToApply = AggregateFunction.Max;

IGroupByCollection groupByClause = new GroupByCollection();
groupByClause.Add(fields["FeeRange"]);
groupByClause.Add(fields["ServiceName"]);
groupByClause.Add(fields["ServiceUrl"]);
groupByClause.Add(fields["Type"]);
groupByClause.Add(fields["KeyService"]);
groupByClause.Add(fields["KeyFserviceCategory"]);
groupByClause.Add(fields["ServiceCategory"]);
groupByClause.Add(fields["ServiceCategoryUrl"]);

// Get record count
int iRecordCount = (int)adapter.GetScalar(fields["KeyFserviceContent"], null, AggregateFunction.CountRow, filter.PredicateExpression, groupByClause, filter.Relations);
            
// Get data
adapter.FetchTypedList(fields, (System.Data.DataTable) tlServicesSummary, filter, 0, sorter, false, groupByClause, c_LLBLPager.CurrentPage, c_LLBLPager.PageSize);

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 25-Feb-2005 11:21:25   

The getscalar replaces the aggregate on teh field with the COUNT(*) aggregate.

So the query will become SELECT COUNT(*) FROM ... WHERE ... GROUP BY .. , I think you want to perform a COUNT, not a count row.

Frans Bouma | Lead developer LLBLGen Pro
John
User
Posts: 28
Joined: 15-Jan-2005
# Posted on: 25-Feb-2005 12:20:22   

I think you mean changing this line to this:

// Get record count int iRecordCount = (int)adapter.GetScalar(fields["KeyFserviceContent"], null, AggregateFunction.Count, filter.PredicateExpression, groupByClause, filter.Relations);

I have done this and it doesnt make any difference, I still get 2 records?

p.s. Is there a way to write out the SQL being generated in a trace for example?

Thanks

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 25-Feb-2005 12:37:54   

John wrote:

I think you mean changing this line to this:

// Get record count int iRecordCount = (int)adapter.GetScalar(fields["KeyFserviceContent"], null, AggregateFunction.Count, filter.PredicateExpression, groupByClause, filter.Relations);

I have done this and it doesnt make any difference, I still get 2 records?

Hmm.

p.s. Is there a way to write out the SQL being generated in a trace for example? Thanks

GetScalar doesn't have an OnGetScalar() yet (was an oversight), so you have to do it the non-easy way:

In DataAccessAdapter.CreateSelectDQ, you'll see:


            return DynamicQueryEngine.CreateSelectDQ(fieldsToFetch.GetAsEntityFieldCoreArray(),
                persistenceInfoObjects, base.GetActiveConnection(), filter, maxNumberOfItemsToReturn, sortClauses, relationsToWalk, allowDuplicates, groupByClause, pageNumber, pageSize);

Change that line into

IRetrievalQuery query = DynamicQueryEngine.CreateSelectDQ(fieldsToFetch.GetAsEntityFieldCoreArray(), persistenceInfoObjects, base.GetActiveConnection(), filter, maxNumberOfItemsToReturn, sortClauses, relationsToWalk, allowDuplicates, groupByClause, pageNumber, pageSize); return query;

  • recompile.
  • set a breakpoint on the line you quoted above, and also on the first statement in DataAccessAdapter.CreateSelectDQ(). Then run the debugger and break on that second statement. Eventually you've to set the second breakpoint after you've stopped at the line above.

Step over the creation of the query call (first line in CreateSelectDQ), and in the locals window in the debugger you'll see the 'query' object. Click it open till you see the Command and its CommandText property. That's the query.

You can also use sqlprofiler.

Frans Bouma | Lead developer LLBLGen Pro
John
User
Posts: 28
Joined: 15-Jan-2005
# Posted on: 25-Feb-2005 14:58:01   

Errr OK I think I wont worry about getting the SQL wink

What do you suggest with the paging problem though, I dont see how I can progress other than for example running the query without paging and counting the rows in the returned typed list. I dont really want todo this however as its not very efficient? Thanks

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 25-Feb-2005 15:32:37   

John wrote:

Errr OK I think I wont worry about getting the SQL wink

Still I'd like to ask you to try it if you have the time. If there is a bug somewhere I'd like to fix it.

What do you suggest with the paging problem though, I dont see how I can progress other than for example running the query without paging and counting the rows in the returned typed list. I dont really want todo this however as its not very efficient? Thanks

Paging on a typedlist/view is using the ADO.NET dataadapter paging code, i.e.: it reads teh complete set, and skips till it runs into the row it needs to start on. the scalar query should return the right amount of rows, as it simply executes the same query, but performs a count(*)... at least that's what should happen.

Frans Bouma | Lead developer LLBLGen Pro
John
User
Posts: 28
Joined: 15-Jan-2005
# Posted on: 25-Feb-2005 17:46:15   

OK I think I did that right, I'm sorry but I'm not very familiar with debugging (in fact I've never used it).

This is what was in there (which doesnt make any sense to me)


CommandText "SELECT [Housingcare].[dbo].[SER_ServiceCategories].[KeyServiceCategory] AS [KeyServiceCategory],[Housingcare].[dbo].[SER_ServiceCategories].[ServiceCategory] AS [ServiceCategory],[Housingcare].[dbo].[SER_ServiceCategories].[ServiceCategoryUrl] AS [ServiceCategoryUrl] FROM [Housingcare].[dbo].[SER_ServiceCategories] WHERE ( [Housingcare].[dbo].[SER_ServiceCategories].[KeyServiceCategory] = @KeyServiceCategory1)" string

This is what was in the query object on the line which actually returns the TypedList e.g. adapter.FetchTypedList(fields, (System.Data.DataTable) tlServicesSummary, filter, 0, sorter, false, groupByClause, c_LLBLPager.CurrentPage, c_LLBLPager.PageSize);


CommandText "CREATE TABLE #TempTable ([__rowcnt][int] IDENTITY (1,1) NOT NULL,[FeeRange][NVarChar](200) NULL,[ServiceName][NVarChar](200) NULL,[ServiceUrl][NVarChar](200) NULL,[Type][NVarChar](200) NULL,[KeyService][Int] NULL,[KeyFserviceCategory][Int] NULL,[ServiceCategory][NVarChar](200) NULL,[ServiceCategoryUrl][NVarChar](200) NULL,[KeyFserviceContent][Int] NULL);INSERT INTO #TempTable ([FeeRange],[ServiceName],[ServiceUrl],[Type],[KeyService],[KeyFserviceCategory],[ServiceCategory], [ServiceCategoryUrl],[KeyFserviceContent])SELECT DISTINCT [Housingcare].[dbo].[SER_ServiceFees].[FeeRange] AS [FeeRange],[Housingcare].[dbo].[SER_Services].[ServiceName] AS [ServiceName],[Housingcare].[dbo].[SER_Services].[ServiceUrl] AS [ServiceUrl],[Housingcare].[dbo].[SER_ServiceTypes].[Type] AS [Type],[Housingcare].[dbo].[SER_Services].[KeyService] AS [KeyService],[Housingcare].[dbo].[SER_Services].[KeyFServiceCategory] AS [KeyFserviceCategory],[Housingcare].[dbo].[SER_ServiceCategories].[ServiceCategory] AS [ServiceCategory],[Housingcare].[dbo].[SER_ServiceCategories].[ServiceCategoryUrl] AS [ServiceCategoryUrl],MAX([Housingcare].[dbo].[SER_ServiceContentsAlloc].[KeyFServiceContent]) AS [KeyFserviceContent] FROM (((( [Housingcare].[dbo].[SER_ServiceTypes] INNER JOIN [Housingcare].[dbo].[SER_Services] ON  [Housingcare].[dbo].[SER_ServiceTypes].[KeyServiceType]=[Housingcare].[dbo].[SER_Services].[KeyFServiceType]) INNER JOIN [Housingcare].[dbo].[SER_ServiceFees] ON  [Housingcare].[dbo].[SER_ServiceFees].[KeyFee]=[Housingcare].[dbo].[SER_Services].[KeyFFee]) INNER JOIN [Housingcare].[dbo].[SER_ServiceCategories] ON  [Housingcare].[dbo].[SER_ServiceCategories].[KeyServiceCategory]=[Housingcare].[dbo].[SER_Services].[KeyFServiceCategory]) INNER JOIN [Housingcare].[dbo].[SER_ServiceContentsAlloc] ON  [Housingcare].[dbo].[SER_Services].[KeyService]=[Housingcare].[dbo].[SER_ServiceContentsAlloc].[KeyFService]) WHERE ( [Housingcare].[dbo].[SER_Services].[KeyFServiceCategory] = @KeyFserviceCategory1) GROUP BY [Housingcare].[dbo].[SER_ServiceFees].[FeeRange],[Housingcare].[dbo].[SER_Services].[ServiceName], [Housingcare].[dbo].[SER_Services].[ServiceUrl],[Housingcare].[dbo].[SER_ServiceTypes].[Type], [Housingcare].[dbo].[SER_Services].[KeyService],[Housingcare].[dbo].[SER_Services].[KeyFServiceCategory], [Housingcare].[dbo].[SER_ServiceCategories].[ServiceCategory],[Housingcare].[dbo].[SER_ServiceCategories].[ServiceCategoryUrl] ORDER BY [Housingcare].[dbo].[SER_Services].[ServiceName] ASC;SELECT [FeeRange],[ServiceName],[ServiceUrl],[Type],[KeyService],[KeyFserviceCategory], [ServiceCategory],[ServiceCategoryUrl],[KeyFserviceContent] FROM #TempTable WHERE [__rowcnt] > 0 AND [__rowcnt] <= 6;DROP TABLE #TempTable"  string

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 25-Feb-2005 20:32:46   

John wrote:

OK I think I did that right, I'm sorry but I'm not very familiar with debugging (in fact I've never used it).

This is what was in there (which doesnt make any sense to me)


CommandText "SELECT [Housingcare].[dbo].[SER_ServiceCategories].[KeyServiceCategory] AS [KeyServiceCategory],[Housingcare].[dbo].[SER_ServiceCategories].[ServiceCategory] AS [ServiceCategory],[Housingcare].[dbo].[SER_ServiceCategories].[ServiceCategoryUrl] AS [ServiceCategoryUrl] FROM [Housingcare].[dbo].[SER_ServiceCategories] WHERE ( [Housingcare].[dbo].[SER_ServiceCategories].[KeyServiceCategory] = @KeyServiceCategory1)" string

This is your getscalar query, so if you open query analyzer and run: SELECT [Housingcare].[dbo].[SER_ServiceCategories].[KeyServiceCategory] AS [KeyServiceCategory],[Housingcare].[dbo].[SER_ServiceCategories].[ServiceCategory] AS [ServiceCategory],[Housingcare].[dbo].[SER_ServiceCategories].[ServiceCategoryUrl] AS [ServiceCategoryUrl] FROM [Housingcare].[dbo].[SER_ServiceCategories] WHERE ( [Housingcare].[dbo].[SER_ServiceCategories].[KeyServiceCategory] = @KeyServiceCategory1)

and for @KeyServiceGategor1 you have to specify the value you want to filter on.

What I find odd is that there isn't any aggregate specified. confused

This is what was in the query object on the line which actually returns the TypedList e.g. adapter.FetchTypedList(fields, (System.Data.DataTable) tlServicesSummary, filter, 0, sorter, false, groupByClause, c_LLBLPager.CurrentPage, c_LLBLPager.PageSize);


CommandText "CREATE TABLE #TempTable ([__rowcnt][int] IDENTITY (1,1) NOT NULL,[FeeRange][NVarChar](200) NULL,[ServiceName][NVarChar](200) NULL,[ServiceUrl][NVarChar](200) NULL,[Type][NVarChar](200) NULL,[KeyService][Int] NULL,[KeyFserviceCategory][Int] NULL,[ServiceCategory][NVarChar](200) NULL,[ServiceCategoryUrl][NVarChar](200) NULL,[KeyFserviceContent][Int] NULL);INSERT INTO #TempTable ([FeeRange],[ServiceName],[ServiceUrl],[Type],[KeyService],[KeyFserviceCategory],[ServiceCategory], [ServiceCategoryUrl],[KeyFserviceContent])SELECT DISTINCT [Housingcare].[dbo].[SER_ServiceFees].[FeeRange] AS [FeeRange],[Housingcare].[dbo].[SER_Services].[ServiceName] AS [ServiceName],[Housingcare].[dbo].[SER_Services].[ServiceUrl] AS [ServiceUrl],[Housingcare].[dbo].[SER_ServiceTypes].[Type] AS [Type],[Housingcare].[dbo].[SER_Services].[KeyService] AS [KeyService],[Housingcare].[dbo].[SER_Services].[KeyFServiceCategory] AS [KeyFserviceCategory],[Housingcare].[dbo].[SER_ServiceCategories].[ServiceCategory] AS [ServiceCategory],[Housingcare].[dbo].[SER_ServiceCategories].[ServiceCategoryUrl] AS [ServiceCategoryUrl],MAX([Housingcare].[dbo].[SER_ServiceContentsAlloc].[KeyFServiceContent]) AS [KeyFserviceContent] FROM (((( [Housingcare].[dbo].[SER_ServiceTypes] INNER JOIN [Housingcare].[dbo].[SER_Services] ON  [Housingcare].[dbo].[SER_ServiceTypes].[KeyServiceType]=[Housingcare].[dbo].[SER_Services].[KeyFServiceType]) INNER JOIN [Housingcare].[dbo].[SER_ServiceFees] ON  [Housingcare].[dbo].[SER_ServiceFees].[KeyFee]=[Housingcare].[dbo].[SER_Services].[KeyFFee]) INNER JOIN [Housingcare].[dbo].[SER_ServiceCategories] ON  [Housingcare].[dbo].[SER_ServiceCategories].[KeyServiceCategory]=[Housingcare].[dbo].[SER_Services].[KeyFServiceCategory]) INNER JOIN [Housingcare].[dbo].[SER_ServiceContentsAlloc] ON  [Housingcare].[dbo].[SER_Services].[KeyService]=[Housingcare].[dbo].[SER_ServiceContentsAlloc].[KeyFService]) WHERE ( [Housingcare].[dbo].[SER_Services].[KeyFServiceCategory] = @KeyFserviceCategory1) GROUP BY [Housingcare].[dbo].[SER_ServiceFees].[FeeRange],[Housingcare].[dbo].[SER_Services].[ServiceName], [Housingcare].[dbo].[SER_Services].[ServiceUrl],[Housingcare].[dbo].[SER_ServiceTypes].[Type], [Housingcare].[dbo].[SER_Services].[KeyService],[Housingcare].[dbo].[SER_Services].[KeyFServiceCategory], [Housingcare].[dbo].[SER_ServiceCategories].[ServiceCategory],[Housingcare].[dbo].[SER_ServiceCategories].[ServiceCategoryUrl] ORDER BY [Housingcare].[dbo].[SER_Services].[ServiceName] ASC;SELECT [FeeRange],[ServiceName],[ServiceUrl],[Type],[KeyService],[KeyFserviceCategory], [ServiceCategory],[ServiceCategoryUrl],[KeyFserviceContent] FROM #TempTable WHERE [__rowcnt] > 0 AND [__rowcnt] <= 6;DROP TABLE #TempTable"  string

This goo is the full typed list query and the extra stuff required to make paging possible: it uses a temp table and loads the data in tehre first, then loads the required rows from there and returns these.

So the issue is in the first query which doesn't look like anything like the second query. Are you sure you checked at the right spot when you called GetScalar?

Frans Bouma | Lead developer LLBLGen Pro
John
User
Posts: 28
Joined: 15-Jan-2005
# Posted on: 26-Feb-2005 12:31:09   

OK getting hang of debugger....

Based on same code this line:

// Get record count int iRecordCount = (int)adapter.GetScalar(fields["KeyFserviceContent"], null, AggregateFunction.Count, filter.PredicateExpression, groupByClause, filter.Relations);

Produces:


CommandText "SELECT TOP 1 COUNT([Housingcare].[dbo].[SER_ServiceContentsAlloc].[KeyFServiceContent]) AS [KeyFserviceContent] FROM (((( [Housingcare].[dbo].[SER_ServiceTypes] INNER JOIN [Housingcare].[dbo].[SER_Services] ON  [Housingcare].[dbo].[SER_ServiceTypes].[KeyServiceType]=[Housingcare].[dbo].[SER_Services].[KeyFServiceType]) INNER JOIN [Housingcare].[dbo].[SER_ServiceFees] ON  [Housingcare].[dbo].[SER_ServiceFees].[KeyFee]=[Housingcare].[dbo].[SER_Services].[KeyFFee]) INNER JOIN [Housingcare].[dbo].[SER_ServiceCategories] ON  [Housingcare].[dbo].[SER_ServiceCategories].[KeyServiceCategory]=[Housingcare].[dbo].[SER_Services].[KeyFServiceCategory]) INNER JOIN [Housingcare].[dbo].[SER_ServiceContentsAlloc] ON  [Housingcare].[dbo].[SER_Services].[KeyService]=[Housingcare].[dbo].[SER_ServiceContentsAlloc].[KeyFService]) WHERE ( [Housingcare].[dbo].[SER_Services].[KeyFServiceCategory] = @KeyFserviceCategory1) GROUP BY [Housingcare].[dbo].[SER_ServiceFees].[FeeRange],[Housingcare].[dbo].[SER_Services].[ServiceName], [Housingcare].[dbo].[SER_Services].[ServiceUrl],[Housingcare].[dbo].[SER_ServiceTypes].[Type], [Housingcare].[dbo].[SER_Services].[KeyService],[Housingcare].[dbo].[SER_Services].[KeyFServiceCategory], [Housingcare].[dbo].[SER_ServiceCategories].[ServiceCategory], [Housingcare].[dbo].[SER_ServiceCategories].[ServiceCategoryUrl]"   string

iRecordCount = 2 after execution


I then added in a line with the original paging code, without AggregateFunction.Max, or a GroupByClause, and WITH the original AggregateFunction.CountRow a la:

ResultsetFields fields1 = (ResultsetFields) tlServicesSummary.GetFieldsInfo(); int iRecordCount1 = (int)adapter.GetScalar(fields1[0], null, AggregateFunction.CountRow, filter.PredicateExpression, null, filter.Relations); Trace.Warn("iRecordCount1: " + iRecordCount1.ToString());

This produced:


CommandText "SELECT TOP 1 COUNT(*) AS [FeeRange] FROM (((( [Housingcare].[dbo].[SER_ServiceTypes] INNER JOIN [Housingcare].[dbo].[SER_Services] ON  [Housingcare].[dbo].[SER_ServiceTypes].[KeyServiceType]=[Housingcare].[dbo].[SER_Services].[KeyFServiceType]) INNER JOIN [Housingcare].[dbo].[SER_ServiceFees] ON  [Housingcare].[dbo].[SER_ServiceFees].[KeyFee]=[Housingcare].[dbo].[SER_Services].[KeyFFee]) INNER JOIN [Housingcare].[dbo].[SER_ServiceCategories] ON  [Housingcare].[dbo].[SER_ServiceCategories].[KeyServiceCategory]=[Housingcare].[dbo].[SER_Services].[KeyFServiceCategory]) INNER JOIN [Housingcare].[dbo].[SER_ServiceContentsAlloc] ON  [Housingcare].[dbo].[SER_Services].[KeyService]=[Housingcare].[dbo].[SER_ServiceContentsAlloc].[KeyFService]) WHERE ( [Housingcare].[dbo].[SER_Services].[KeyFServiceCategory] = @KeyFserviceCategory1)"    string

iRecordCount1 = 141 after execution


Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 26-Feb-2005 14:53:20   

Ok I'll look into it.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 28-Feb-2005 11:11:41   

The second query misses teh group by. It's key that you pass in the same elements to the scalar and the normal fetch method: group by, predicateexpression and relationcollection (i.e the RelationPredicateBucket). If you don't pass in the groupby collection for example you get different results, obviously.

Frans Bouma | Lead developer LLBLGen Pro
John
User
Posts: 28
Joined: 15-Jan-2005
# Posted on: 28-Feb-2005 15:33:25   

I have though have I not if you look back to the original code?

// Get record count int iRecordCount = (int)adapter.GetScalar(fields["KeyFserviceContent"], null, AggregateFunction.CountRow, filter.PredicateExpression, groupByClause, filter.Relations);

// Get data adapter.FetchTypedList(fields, (System.Data.DataTable) tlServicesSummary, filter, 0, sorter, false, groupByClause, c_LLBLPager.CurrentPage, c_LLBLPager.PageSize);

These are both being passed the same elements and same groupby clause, yet they produce different results, this was my original problem?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 28-Feb-2005 16:05:55   

John wrote:

I have though have I not if you look back to the original code?

// Get record count int iRecordCount = (int)adapter.GetScalar(fields["KeyFserviceContent"], null, AggregateFunction.CountRow, filter.PredicateExpression, groupByClause, filter.Relations);

// Get data adapter.FetchTypedList(fields, (System.Data.DataTable) tlServicesSummary, filter, 0, sorter, false, groupByClause, c_LLBLPager.CurrentPage, c_LLBLPager.PageSize);

These are both being passed the same elements and same groupby clause, yet they produce different results, this was my original problem?

Ok, so you pass in the same elements, yet in one of them the groupby is not used, ok, I'll look into it. I just saw in teh SQL that one query was much larger than the other, so definitely not the same query.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 28-Feb-2005 19:18:00   

The problem is this:

When you use a GroupBy clause and a COUNT(), the COUNT() is used in conjunction with teh GroupBy, not with the set. This means that if there are more than one row returned from the normal query, the count(*) will only count the distinct rows.

So if I have: select COUNT(*) AS RowC FROM Orders O INNER JOIN Customers C ON O.CustomerID = C.CustomerID WHERE C.CustomerID = 'CACTU' GROUP BY C.CompanyName, C.ContactName, O.OrderID

it returns 6 rows with '1', while it should return 6.

The query which does this is: select COUNT(*) FROM (SELECT .... FROM Orders O INNER JOIN Customers C ON O.CustomerID = C.CustomerID WHERE C.CustomerID = 'CACTU' GROUP BY C.CompanyName, C.ContactName, O.OrderID) AS TempResult

This returns 6.

The current code can't formulate such a query at the moment, as it has to select from a select set. You can try to mimic the result by removing unique fields from the groupby collection you're using for the GetScalar

I'll see if I can fix this in another way.

Frans Bouma | Lead developer LLBLGen Pro
John
User
Posts: 28
Joined: 15-Jan-2005
# Posted on: 01-Mar-2005 11:20:02   

I am not sure if I have made myself clear and am not confusing you confused

I need both queries to be 100% identical with the same recordset returned for both (obviously the paged one will filter the correct rows from the main recordset), so I dont quite understand why the following is not applied on the GetScalar method as well?

fields["KeyFserviceContent"].AggregateFunctionToApply = AggregateFunction.Max;

Applying this aggregate function combined with a GroupBy clause is the key to removing duplicated rows on a 1:m relationship, and I need the same query run in both circumstances.

Thanks for your help

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 01-Mar-2005 12:06:47   

John wrote:

I am not sure if I have made myself clear and am not confusing you confused

yes you have, and you ran into an issue with the current code. simple_smile

I need both queries to be 100% identical with the same recordset returned for both (obviously the paged one will filter the correct rows from the main recordset), so I dont quite understand why the following is not applied on the GetScalar method as well?

fields["KeyFserviceContent"].AggregateFunctionToApply = AggregateFunction.Max;

Applying this aggregate function combined with a GroupBy clause is the key to removing duplicated rows on a 1:m relationship, and I need the same query run in both circumstances.

Please understand that I don't have your application here, so it's sometimes a bit hard for me to understand what results are if you just change a line, as I don't see the exact call you've made: if you called the same line with the aggregate you specify above, then you'll get AggregateFunction.CountRow applied to fields["KeyFserviceContent"], as that's what you're telling getscalar.

The problem with the current code is that it doesn't offer you a true getrowcount feature. This means you have to construct taht from the query you're trying to execute and apply a CountRow on that, as you've tried.

This doesn't work, and that's my code's fault, not yours, as it applies the COUNT() to the query with the groupby. But when that is done, the COUNT() doesn't simply count the amount of rows, it does that per group returned by the group by is applied, and thus returns wrong results. What should be done is that the DQE's generate a wrapped query: SELECT COUNT(*) AS DBCount FROM (your query here) AS TempResults.

That will always return the correct amount of rows. As this requires architectural changes I'll make this change in the upgrade which goes into beta this week. At the moment there is no other way to get the rowcount using the current code with your query. That's a problem in the current code, which I hope to address with the architectural changes I described above.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 01-Mar-2005 17:17:22   

I've fixed this in 1.0.2004.2, which hopefully goes beta this week. I've added DataAccessAdapter.GetDbCount() which accepts your query elements and which does return the correct value. I hope you can wait a few weeks.

Frans Bouma | Lead developer LLBLGen Pro
John
User
Posts: 28
Joined: 15-Jan-2005
# Posted on: 02-Mar-2005 11:34:32   

No thats fine dont worry, your support is brilliant and I appreciate your looking into it very much. I've hacked it in the meantime by just returning a separate TypedList without paging and counting the rows, very naughty I know but it works (which is my style of coding simple_smile )

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 02-Mar-2005 11:56:27   

John wrote:

No thats fine dont worry, your support is brilliant and I appreciate your looking into it very much. I've hacked it in the meantime by just returning a separate TypedList without paging and counting the rows, very naughty I know but it works (which is my style of coding simple_smile )

heh simple_smile

It also could probably be done by a different groupby + field query, but that's trial and error..

Frans Bouma | Lead developer LLBLGen Pro