The PrefetchPathElement you to tried to add is already added to this PrefetchPath.

Posts   
 
    
shware
User
Posts: 23
Joined: 14-May-2007
# Posted on: 16-Apr-2008 18:59:54   

Hi,

Using the Northwind database and LGP from the UnitTests (modified to get things working).

Using following Linq from the beta doc:


        using (DataAccessAdapter adapter = new DataAccessAdapter())
        {

            
            LinqMetaData metaData = new LinqMetaData(adapter);
            var customers = (from c in metaData.Customer
                             where c.Country == "Germany"
                             select c).WithPath(new PathEdge<OrderEntity>(CustomerEntity.PrefetchPathOrders, new PathEdge<OrderDetailEntity>( OrderEntity.PrefetchPathOrderDetails)));

}

Then try to get a count (which works):


Response.Write(customers.Count());

Then try to bind results to datagrid:


dGridCustomers.DataSource = customers;
dGridCustomers.DataBind();

Errors on databind with following output:



 The PrefetchPathElement you to tried to add is already added to this PrefetchPath.
Parameter name: elementToAdd
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.ArgumentException: The PrefetchPathElement you to tried to add is already added to this PrefetchPath.
Parameter name: elementToAdd

Source Error:

Line 1400:              foreach(PathEdgeExpression edge in edges)
Line 1401:              {
Line 1402:                  pathAsAdapter.Add((IPrefetchPathElement2)edge.PathElement, edge.Limiter, edge.PathElement.Filter, edge.PathElement.FilterRelations, 
Line 1403:                              edge.Sorter, null, edge.FieldsToExcludeInclude);
Line 1404:              }


Source File: C:\Program Files\Solutions Design\LLBLGen Pro v2.6 Beta\Sourcecode\LinqSupportClasses\LinqUtils.cs Line: 1402

Stack Trace:

[ArgumentException: The PrefetchPathElement you to tried to add is already added to this PrefetchPath.
Parameter name: elementToAdd]
   SD.LLBLGen.Pro.ORMSupportClasses.PrefetchPath2.Add(IPrefetchPathElement2 elementToAdd, Int32 maxAmountOfItemsToReturn, IPredicateExpression additionalFilter, IRelationCollection additionalFilterRelations, ISortExpression additionalSorter, IEntityFactory2 entityFactoryToUse, ExcludeIncludeFieldsList excludedIncludedFields) +608
   SD.LLBLGen.Pro.LinqSupportClasses.LinqUtils.AddPathEdgesToPrefetchPath(IPrefetchPathCore path, List`1 edges) in C:\Program Files\Solutions Design\LLBLGen Pro v2.6 Beta\Sourcecode\LinqSupportClasses\LinqUtils.cs:1402
   SD.LLBLGen.Pro.LinqSupportClasses.LinqUtils.AddPathEdgesToPrefetchPathElement(IPrefetchPathElementCore pathElement, List`1 edges) in C:\Program Files\Solutions Design\LLBLGen Pro v2.6 Beta\Sourcecode\LinqSupportClasses\LinqUtils.cs:1429
   SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandlePathEdgeExpression(PathEdgeExpression expressionToHandle) in C:\Program Files\Solutions Design\LLBLGen Pro v2.6 Beta\Sourcecode\LinqSupportClasses\ExpressionHandlers\QueryExpressionBuilder.cs:163
   SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle) in C:\Program Files\Solutions Design\LLBLGen Pro v2.6 Beta\Sourcecode\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:203
   SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleExpression(Expression expressionToHandle) in C:\Program Files\Solutions Design\LLBLGen Pro v2.6 Beta\Sourcecode\LinqSupportClasses\ExpressionHandlers\QueryExpressionBuilder.cs:117
   SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandlePrefetchPathEdges(ReadOnlyCollection`1 edgeExpressions) in C:\Program Files\Solutions Design\LLBLGen Pro v2.6 Beta\Sourcecode\LinqSupportClasses\ExpressionHandlers\QueryExpressionBuilder.cs:3263
   SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandlePrefetchPathExpression(PrefetchPathExpression expressionToHandle) in C:\Program Files\Solutions Design\LLBLGen Pro v2.6 Beta\Sourcecode\LinqSupportClasses\ExpressionHandlers\QueryExpressionBuilder.cs:180
   SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle) in C:\Program Files\Solutions Design\LLBLGen Pro v2.6 Beta\Sourcecode\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:206
   SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleExpression(Expression expressionToHandle) in C:\Program Files\Solutions Design\LLBLGen Pro v2.6 Beta\Sourcecode\LinqSupportClasses\ExpressionHandlers\QueryExpressionBuilder.cs:117
   SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleSelectExpression(SelectExpression expressionToHandle, SelectExpression newInstance) in C:\Program Files\Solutions Design\LLBLGen Pro v2.6 Beta\Sourcecode\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:808
   SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleSelectExpression(SelectExpression expressionToHandle) in C:\Program Files\Solutions Design\LLBLGen Pro v2.6 Beta\Sourcecode\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:787
   SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleSelectExpression(SelectExpression expressionToHandle) in C:\Program Files\Solutions Design\LLBLGen Pro v2.6 Beta\Sourcecode\LinqSupportClasses\ExpressionHandlers\QueryExpressionBuilder.cs:2414
   SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle) in C:\Program Files\Solutions Design\LLBLGen Pro v2.6 Beta\Sourcecode\LinqSupportClasses\ExpressionHandlers\GenericExpressionHandler.cs:215
   SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleExpression(Expression expressionToHandle) in C:\Program Files\Solutions Design\LLBLGen Pro v2.6 Beta\Sourcecode\LinqSupportClasses\ExpressionHandlers\QueryExpressionBuilder.cs:117
   SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.HandleExpressionTree(Expression expression) in C:\Program Files\Solutions Design\LLBLGen Pro v2.6 Beta\Sourcecode\LinqSupportClasses\LLBLGenProProviderBase.cs:147
   SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.Execute(Expression expression) in C:\Program Files\Solutions Design\LLBLGen Pro v2.6 Beta\Sourcecode\LinqSupportClasses\LLBLGenProProviderBase.cs:91
   SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.System.Linq.IQueryProvider.Execute(Expression expression) in C:\Program Files\Solutions Design\LLBLGen Pro v2.6 Beta\Sourcecode\LinqSupportClasses\LLBLGenProProviderBase.cs:717
   SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProQuery`1.Execute() in C:\Program Files\Solutions Design\LLBLGen Pro v2.6 Beta\Sourcecode\LinqSupportClasses\LLBLGenProQuery.cs:84
   SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProQuery`1.System.Collections.IEnumerable.GetEnumerator() in C:\Program Files\Solutions Design\LLBLGen Pro v2.6 Beta\Sourcecode\LinqSupportClasses\LLBLGenProQuery.cs:158
   System.Web.UI.WebControls.PagedDataSource.GetEnumerator() +171
   System.Web.UI.WebControls.DataGrid.CreateAutoGeneratedColumns(PagedDataSource dataSource) +254
   System.Web.UI.WebControls.DataGrid.CreateColumnSet(PagedDataSource dataSource, Boolean useDataSource) +1629786
   System.Web.UI.WebControls.DataGrid.CreateControlHierarchy(Boolean useDataSource) +295
   System.Web.UI.WebControls.BaseDataList.OnDataBinding(EventArgs e) +56
   System.Web.UI.WebControls.BaseDataList.DataBind() +52
   _Default.Page_Load(Object sender, EventArgs e) +1363
   System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +15
   System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +33
   System.Web.UI.Control.OnLoad(EventArgs e) +99
   System.Web.UI.Control.LoadRecursive() +47
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1436


Hope this helps,

Shawn

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39903
Joined: 17-Aug-2003
# Posted on: 16-Apr-2008 20:42:48   

Will check it out simple_smile

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39903
Joined: 17-Aug-2003
# Posted on: 21-Apr-2008 12:00:09   

It's reproducable if the query is enumerated again:




[Test]
public void GetCustomersFromGermanyWithRelatedOrdersAndOrderDetails()
{
    using(DataAccessAdapter adapter = new DataAccessAdapter())
    {
        LinqMetaData metaData = new LinqMetaData(adapter);
        var q = (from c in metaData.Customer
                 where c.Country == "Germany"
                 select c).WithPath(new PathEdge<OrderEntity>(
                                            CustomerEntity.PrefetchPathOrders, 
                                                    new PathEdge<OrderDetailEntity>(OrderEntity.PrefetchPathOrderDetails)));

        int count = 0;
        foreach(var v in q)
        {
            count++;
        }
        Assert.AreEqual(11, count);

        count = 0;
        foreach(var v in q)
        {
            count++;
        }
        Assert.AreEqual(11, count);
    }
}

It adds the prefetch path elements again to the query, which is wrong, as it already did that. I think the datagrid binding re-enumerates the query a couple of times... Looking into it.

(edit). The second execution re-evaluates the complete tree again, which means the PrefetchpathElement(2) objects are added to the right path element again. This causes the problem.

We're currently looking into caching the results per query so re-enumerating the same query simply re-enumerates the previous results. This is also the behavior of linq to sql (which doesn't execute the query again). Caching the results is inside the provider inside the linq query.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39903
Joined: 17-Aug-2003
# Posted on: 21-Apr-2008 13:22:19   

It was simpler: simply clearing the subpath when the PathEdge object was created solved it. The issue was caused by the fact that an actual IPrefetchPathElement(2) instance was passed to the PathEdge ctor, so the expression tree doesn't have a call to the prefetch path property on the entity type, but just a pathedge which contains the element already. Rebuilding the path thus leads to duplicate elements inside the element's subpath property.

Fixed in next build.

Frans Bouma | Lead developer LLBLGen Pro
shware
User
Posts: 23
Joined: 14-May-2007
# Posted on: 21-Apr-2008 18:49:59   

Downloaded latest build and things work fine simple_smile

edit: sorry I didn't mean to reset the "finished" indicate flushed

Thanks!

Shawn

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39903
Joined: 17-Aug-2003
# Posted on: 21-Apr-2008 19:26:25   

Glad it's solved! simple_smile

Frans Bouma | Lead developer LLBLGen Pro