- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
The PrefetchPathElement you to tried to add is already added to this PrefetchPath.
Joined: 14-May-2007
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
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.
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.