linqQuery.Count() problem

Posts   
 
    
harmen
User
Posts: 47
Joined: 22-Jun-2007
# Posted on: 02-Oct-2009 08:52:27   

Hi, I have the following linq query:

        
    public class MedewerkerUrenPostQuery
    {
        public int? MedewerkerID { get; set; }
        public int? UrenPostID { get; set; }
        public bool AlleenTeTonenPosten { get; set; }

        public IQueryable<MedewerkerUrenPost> GetQuery(LinqMetaData db)
        {
            var medewerkerUrenPostQuery =
                from m in db.MedewerkerUrenPost
                select new
                {
                    m.MedewerkerID,
                    m.UrenPostID,
                    m.MagGetoondWorden
                };

            if (MedewerkerID.HasValue)
                medewerkerUrenPostQuery = medewerkerUrenPostQuery.Where(x => x.MedewerkerID == MedewerkerID);

            if (UrenPostID.HasValue)
                medewerkerUrenPostQuery = medewerkerUrenPostQuery.Where(x => x.UrenPostID == UrenPostID);

            if (AlleenTeTonenPosten)
                medewerkerUrenPostQuery = medewerkerUrenPostQuery.Where(x => x.MagGetoondWorden);

            return
                from m in medewerkerUrenPostQuery
                join p in db.UrenPost on m.UrenPostID equals p.ID
                select new MedewerkerUrenPost()
                {
                    MedewerkerID = m.MedewerkerID,
                    UrenPostID = m.UrenPostID,
                    MagGetoondWorden = m.MagGetoondWorden,
                    CoderingBedrijfNummer = p.CoderingBedrijfNummer,
                    SoortCodering = p.SoortCodering,
                    ProjectNummer = p.ProjectNummer,
                    ProjectOmschrijving = p.Werk.Omschrijving,
                    KostenCode = p.KostenCode,
                    AfdelingsNummer = p.AfdelingsNummer,
                    WerkOrderNummer = p.WerkOrderNummer,
                    WerkOrderOmschrijving = p.Werkorder.Omschrijving,
                    BegrotingsCode = p.BegrotingsCode,
                    RekeningNummer = p.RekeningNummer,
                    Kostenplaats = p.Kostenplaats
                };
    }

var q = new MedewerkerUrenPostQuery()
{
     MedewerkerID = this.MedewerkerID,
     AlleenTeTonenPosten = true
}.GetQuery(db);

var result = q.ToList();


Which results in the following sql query (mssql):


SELECT 
    [LPA_L1].[MedewerkerID], 
    [LPA_L1].[UrenPostID], 
    [LPA_L1].[MagGetoondWorden], 
    [LPA_L2].[CoderingBedrijfNummer], 
    [LPA_L2].[SoortCodering], 
    [LPA_L2].[ProjectNummer], 
    [LPA_L3].[OMSCHRIJVING] AS [ProjectOmschrijving], 
    [LPA_L2].[KostenCode], 
    [LPA_L2].[AfdelingsNummer], 
    [LPA_L2].[WerkOrderNummer], 
    [LPA_L4].[OMS_WERKORDER] AS [WerkOrderOmschrijving], 
    [LPA_L2].[BegrotingsCode], 
    [LPA_L2].[RekeningNummer], 
    [LPA_L2].[Kostenplaats] 
FROM ((((
    SELECT 
        [LPA_L6].[MedewerkerID], 
        [LPA_L6].[UrenPostID], 
        [LPA_L6].[MagGetoondWorden] 
    FROM (
        SELECT 
            [LPLA_1].[MedewerkerID], 
            [LPLA_1].[UrenPostID], 
            [LPLA_1].[MagGetoondWorden] 
        FROM [BISNETF3_ERA].[dbo].[MedewerkerUrenPost] [LPLA_1] ) [LPA_L6] 
        WHERE ( ( ( [LPA_L6].[MedewerkerID] = 26)) 
            AND ( [LPA_L6].[MagGetoondWorden] = 1))) [LPA_L1]  
        INNER JOIN [BISNETF3_ERA].[dbo].[UrenPost] [LPA_L2]  
            ON  [LPA_L1].[UrenPostID] = [LPA_L2].[ID]) 
        LEFT JOIN [BISNETF3_ERA].[dbo].[WAWERK] [LPA_L3]  
            ON  [LPA_L3].[BEDRIJF]=[LPA_L2].[CoderingBedrijfNummer] 
            AND [LPA_L3].[WERK_NUMMER]=[LPA_L2].[ProjectNummer]) 
        LEFT JOIN [BISNETF3_ERA].[dbo].[WOORDER] [LPA_L4]  
            ON  [LPA_L4].[BEDRIJF]=[LPA_L2].[CoderingBedrijfNummer] 
            AND [LPA_L4].[AFDELING_NR]=[LPA_L2].[AfdelingsNummer] 
            AND [LPA_L4].[WERKORDER_NR]=[LPA_L2].[WerkOrderNummer])

So far so good. The problems start when I try to do a Count():

Error 1:



int n = q.Count();

[SD.LLBLGen.Pro.ORMSupportClasses.ORMQueryConstructionException]    

"Internal error: QueryExpression of non-entity type without projection encountered without prior source with projection. Did you misplace a where/orderby construct in a multiple-from containing query?"

   at SD.LLBLGen.Pro.LinqSupportClasses.LinqUtils.CreateProjectionForQueryIfNoProjectionAvailable(QueryExpression toExecute, ITemplateGroupSpecificCreator frameworkElementCreator, SetAlias aliasToUse)
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionClasses.QueryExpression.InsertProjectionIfEmpty(SetAlias aliasToUse, ITemplateGroupSpecificCreator frameworkElementCreator)
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleAggregateExpressionReferencingNormalSet(AggregateExpression expressionToHandle, Expression handledSource, QueryExpression handledSourceAsQuery, Expression handledArgument)
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleAggregateExpression(AggregateExpression expressionToHandle)
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle)
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleExpression(Expression expressionToHandle)
   at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.HandleExpressionTree(Expression expression)
   at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.Execute(Expression expression)
   at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.System.Linq.IQueryProvider.Execute[TResult](Expression expression)
   at System.Linq.Queryable.Count[TSource](IQueryable`1 source)
   at Piramide.Bis.WebUI.Urenverantwoording.Controllers.UrenPostController.HaalData() in D:\PirApps\BisNET\2.Ontw\WebApplicatie\BisNetWebF3\Urenverantwoording\Controllers\UrenPostController.cs:line 136
   at Piramide.Bis.WebUI.Urenverantwoording.Controllers.UrenPostController.Zoek() in D:\PirApps\BisNET\2.Ontw\WebApplicatie\BisNetWebF3\Urenverantwoording\Controllers\UrenPostController.cs:line 59


So I thought I need a projecten and tried the simplest projection I could think of.

Error 2:



int n = q.Select(x => x).Count();

[System.ArgumentException]

"An item with the same key has already been added."

   at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionClasses.ProjectionListExpression.AddElement(String name, Object element, Type elementType, Int32 elementIndex)
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionClasses.ProjectionListExpression.AddExpressionElement(String elementName, Type elementType, Expression elementToAdd, Int32 elementIndex, IElementCreatorCore generatedCodeCreator, ITemplateGroupSpecificCreator frameworkElementCreator, MappingTracker trackedMappings, FunctionMappingsContainer functionMappings)
   at SD.LLBLGen.Pro.LinqSupportClasses.LinqUtils.CoerceLinqExpressionToProjectionListExpression(Expression toCoerce, IElementCreatorCore generatedCodeElementCreator, ITemplateGroupSpecificCreator frameworkElementCreator, MappingTracker trackedMappings, FunctionMappingsContainer functionMappings)
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleProjectionExpression(ProjectionExpression expressionToHandle)
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle)
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleExpression(Expression expressionToHandle)
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleSelectExpression(SelectExpression expressionToHandle, SelectExpression newInstance)
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleSelectExpression(SelectExpression expressionToHandle)
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleSelectExpression(SelectExpression expressionToHandle)
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle)
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleExpression(Expression expressionToHandle)
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleAggregateExpression(AggregateExpression expressionToHandle)
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle)
   at SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleExpression(Expression expressionToHandle)
   at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.HandleExpressionTree(Expression expression)
   at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.Execute(Expression expression)
   at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.System.Linq.IQueryProvider.Execute[TResult](Expression expression)
   at System.Linq.Queryable.Count[TSource](IQueryable`1 source)
   at Piramide.Bis.WebUI.Urenverantwoording.Controllers.UrenPostController.HaalData() in D:\PirApps\BisNET\2.Ontw\WebApplicatie\BisNetWebF3\Urenverantwoording\Controllers\UrenPostController.cs:line 138
   at Piramide.Bis.WebUI.Urenverantwoording.Controllers.UrenPostController.Zoek() in D:\PirApps\BisNET\2.Ontw\WebApplicatie\BisNetWebF3\Urenverantwoording\Controllers\UrenPostController.cs:line 59


I finally got it working with:



int n = q.Select(x => x.ID).Count();


Is this expected behaviour? It seems to me that the first two methods I tried should also work. I realy would like to know what this is al about.

Thanks, Harmen

Walaa avatar
Walaa
Support Team
Posts: 14993
Joined: 21-Aug-2005
# Posted on: 02-Oct-2009 10:07:41   

Error 1:

q.Count()

AFAIK, that's not the right way to do this. As you have 2 options:

1- q.ToList().Count(); -> Count the returned list (i.e. counting on the client side after fetching the resultset)

2- q.Select(....).Count(); -> counts on the database side, without fetching the resultset.

Error 2:

q.Select(x => x).Count();

You need to specify fields to project.

harmen
User
Posts: 47
Joined: 22-Jun-2007
# Posted on: 02-Oct-2009 10:18:27   

But the query already contains a select. Why is another select needed?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39862
Joined: 17-Aug-2003
# Posted on: 02-Oct-2009 10:34:40   

could you post the runtime lib version / linq prov. version?

Frans Bouma | Lead developer LLBLGen Pro
harmen
User
Posts: 47
Joined: 22-Jun-2007
# Posted on: 02-Oct-2009 11:35:29   

SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll -> 2.6.8.903 SD.LLBLGen.Pro.LinqSupportClasses.NET35.dll -> 2.6.8.903

Walaa avatar
Walaa
Support Team
Posts: 14993
Joined: 21-Aug-2005
# Posted on: 02-Oct-2009 11:37:39   

2.6.8.903

Definitly you should upgrade to the latest build, as you are using a very old one, and some Linq issues have been fixed since then.

harmen
User
Posts: 47
Joined: 22-Jun-2007
# Posted on: 02-Oct-2009 15:52:38   

Thanks, upgrading solved the problem.

q.Count() just works.