Ordering an IQueryable<T> causes exception (bug)

Posts   
 
    
wtijsma
User
Posts: 252
Joined: 18-Apr-2006
# Posted on: 18-Jun-2008 14:50:45   

Hi,

I seem to be unable to order a dataset on a related entity property, after it has been cast to an IQueryable<T>.

Situation:

  • I have a SalarisniveauschaalEntity with a n:1 relation to SalarisniveauEntity.
  • I want to retrieve a Collection<SalarisniveauschaalEntity> ordered by the related m:1 Salarisniveau property code.

In the following code I've replaced 'var' with the explicit types to make it more clear:


[TestMethod]
public void Test()
{
    var linqMetaData = new LinqMetaData(_adapter);

    IQueryable<SalarisniveauschaalEntity> schalen = from e in linqMetaData.Salarisniveauschaal select e;
    
    schalen = schalen.OrderBy(e => e.Salarisniveau.Code);

    foreach (var entity in schalen)
    {
        Console.WriteLine(entity);
    }
}

this causes an exception:

TestCase 'CC.ECDGenie.Zorg.Test.Zorgovereenkomst.ZorgovereenkomstTests.Test'
failed: SD.LLBLGen.Pro.ORMSupportClasses.ORMRelationException: Relation at index 1 doesn't contain an entity already added to the FROM clause. Bad alias?
    at SD.LLBLGen.Pro.ORMSupportClasses.RelationCollection.PreprocessRelations()
    at SD.LLBLGen.Pro.ORMSupportClasses.RelationCollection.ToQueryTextInternal(Int32& uniqueMarker, Boolean ansiJoins, String& nonAnsiWhereClause, String nonAnsiRootTableReference, String nonAnsiFieldSuffix)
    at SD.LLBLGen.Pro.ORMSupportClasses.RelationCollection.ToQueryText(Int32& uniqueMarker)
    at SD.LLBLGen.Pro.DQE.SqlServer.DynamicQueryEngine.CreateSelectDQ(IEntityFieldCore[] selectList, IFieldPersistenceInfo[] fieldsPersistenceInfo, IDbConnection connectionToUse, IPredicate selectFilter, Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relationsToWalk, Boolean allowDuplicates, IGroupByCollection groupByClause, Boolean relationsSpecified, Boolean sortClausesSpecified)
    at SD.LLBLGen.Pro.ORMSupportClasses.DynamicQueryEngineBase.CreateSelectDQ(IEntityFieldCore[] selectList, IFieldPersistenceInfo[] fieldsPersistenceInfo, IDbConnection connectionToUse, IPredicate selectFilter, Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relationsToWalk, Boolean allowDuplicates, IGroupByCollection groupByClause)
    at SD.LLBLGen.Pro.DQE.SqlServer.DynamicQueryEngine.CreatePagingSelectDQ(IEntityFieldCore[] selectList, IFieldPersistenceInfo[] fieldsPersistenceInfo, IDbConnection connectionToUse, IPredicate selectFilter, Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relationsToWalk, Boolean allowDuplicates, IGroupByCollection groupByClause, Int32 pageNumber, Int32 pageSize)
    at SD.LLBLGen.Pro.ORMSupportClasses.DynamicQueryEngineBase.CreateSelectDQ(IEntityFieldCore[] selectList, IFieldPersistenceInfo[] fieldsPersistenceInfo, IDbConnection connectionToUse, IPredicate selectFilter, Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relationsToWalk, Boolean allowDuplicates, IGroupByCollection groupByClause, Int32 pageNumber, Int32 pageSize)
    at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.CreateSelectDQ(IEntityFields2 fieldsToFetch, IFieldPersistenceInfo[] persistenceInfoObjects, IPredicateExpression filter, Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relationsToWalk, Boolean allowDuplicates, IGroupByCollection groupByClause, Int32 pageNumber, Int32 pageSize)
    D:\Projects\dotNet\Net3.5\CC.ECDGenie\MainLine\Dal\DatabaseSpecific\DataAccessAdapter.User.cs(45,0): at CC.ECDGenie.Dal.DatabaseSpecific.DataAccessAdapter.CreateSelectDQ(IEntityFields2 fieldsToFetch, IFieldPersistenceInfo[] persistenceInfoObjects, IPredicateExpression filter, Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relationsToWalk, Boolean allowDuplicates, IGroupByCollection groupByClause, Int32 pageNumber, Int32 pageSize)
    at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntityCollectionInternal(IEntityCollection2 collectionToFill, IRelationPredicateBucket& filterBucket, Int32 maxNumberOfItemsToReturn, ISortExpression sortClauses, ExcludeIncludeFieldsList excludedIncludedFields, Int32 pageNumber, Int32 pageSize)
    at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntityCollection(IEntityCollection2 collectionToFill, IRelationPredicateBucket filterBucket, Int32 maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath2 prefetchPath, ExcludeIncludeFieldsList excludedIncludedFields, Int32 pageNumber, Int32 pageSize)
    D:\Projects\dotNet\Net3.5\CC.ECDGenie\MainLine\Dal\DatabaseSpecific\DataAccessAdapter.User.cs(51,0): at CC.ECDGenie.Dal.DatabaseSpecific.DataAccessAdapter.FetchEntityCollection(IEntityCollection2 collectionToFill, IRelationPredicateBucket filterBucket, Int32 maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath2 prefetchPath, ExcludeIncludeFieldsList excludedIncludedFields, Int32 pageNumber, Int32 pageSize)
    at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProvider2.ExecuteEntityProjection(QueryExpression toExecute)
    at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.ExecuteExpression(Expression handledExpression)
    at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.Execute(Expression expression)
    at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.System.Linq.IQueryProvider.Execute(Expression expression)
    at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
    D:\Projects\dotNet\Net3.5\CC.ECDGenie\MainLine\CC.ECDGenie.Zorg.Test\Zorgovereenkomst\ZorgovereenkomstTests.cs(73,0): at CC.ECDGenie.Zorg.Test.Zorgovereenkomst.ZorgovereenkomstTests.Test()

with the trace:

Method Enter: DataAccessAdapterBase.StartTransaction
:   Transaction name: DoelpakkettenCatalogusTests. Isolation level: Serializable.
Method Enter: DataAccessAdapterBase.OpenConnection
: New connection created.
: Connection physically opened.
Method Exit: DataAccessAdapterBase.OpenConnection
Method Exit: DataAccessAdapterBase.StartTransaction
: Initial expression to process:
value(SD.LLBLGen.Pro.LinqSupportClasses.DataSource2`1[CC.ECDGenie.Dal.EntityClasses.SalarisniveauschaalEntity]).Select(e => e).OrderBy(e => e.Salarisniveau.Code)
Method Enter: DataAccessAdapterBase.FetchEntityCollection(8)
Method Enter: DataAccessAdapterBase.FetchEntityCollectionInternal(7)
Active Entity Collection Description: 
    EntityCollection: CC.ECDGenie.Dal.HelperClasses.EntityCollection`1[[CC.ECDGenie.Dal.EntityClasses.SalarisniveauschaalEntity, CC.ECDGenie.Dal, Version=1.0.3091.23974, Culture=neutral, PublicKeyToken=null]].   Will contain entities of type: SalarisniveauschaalEntity

Method Enter: CreatePagingSelectDQ
Method Enter: CreateSelectDQ
Method Enter: CreateSelectDQ
Method Enter: DataAccessAdapterBase.Rollback
Method Enter: DataAccessAdapterBase.Reset
Method Exit: DataAccessAdapterBase.Reset
Method Exit: DataAccessAdapterBase.Rollback

The problem seems to be the conversion to IQueryable first, because if I order the DataSource2<SalarisniveauschaalEntity> without assigning it to the 'schalen' variable first, it works fine...

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 18-Jun-2008 15:41:36   

so IQueryable<SalarisniveauschaalEntity> schalen = from e in linqMetaData.Salarisniveauschaal select e; schalen = schalen.OrderBy(e => e.Salarisniveau.Code);

doesn't work but var schalen = from e in linqMetaData.Salarisniveauschaal select e; schalen = schalen.OrderBy(e => e.Salarisniveau.Code);

does? I don't think that's related (both should work)

Also, do you use your filter addition code here?

Frans Bouma | Lead developer LLBLGen Pro
wtijsma
User
Posts: 252
Joined: 18-Apr-2006
# Posted on: 18-Jun-2008 15:51:44   

Otis wrote:

so IQueryable<SalarisniveauschaalEntity> schalen = from e in linqMetaData.Salarisniveauschaal select e; schalen = schalen.OrderBy(e => e.Salarisniveau.Code);

doesn't work but var schalen = from e in linqMetaData.Salarisniveauschaal select e; schalen = schalen.OrderBy(e => e.Salarisniveau.Code);

does? I don't think that's related (both should work)

Also, do you use your filter addition code here?

No I removed the filter addition code, it's a clean DataAccessAdapter simple_smile .

What I mean by not assigning it, this does work:


    var schalen = linqMetaData.Salarisniveauschaal.OrderBy(e => e.Salarisniveau.Code);

but this doesn't:


    var schalen = from e in linqMetaData.Salarisniveauschaal select e;
    schalen = schalen.OrderBy(e => e.Salarisniveau.Code);

Meaning in the first example we're calling OrderBy on the DataSource2<T>, while in the second example we're calling OrderBy on IQueryable<T>. Could this be the problem?.

Should I make a create a project + DDL that reproduces it?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 18-Jun-2008 16:32:25   

I can reproduce it. It's strange

this fails:


IQueryable<OrderEntity> q = from o in metaData.Order
        select o;
q = q.OrderBy(o => o.Customer.Country);

this works:

IQueryable<OrderEntity> q = from o in metaData.Order
        where o.EmployeeId == 2
        select o;
q = q.OrderBy(o => o.Customer.Country);

and... this too:


IQueryable<OrderEntity> q = from o in metaData.Order
    orderby o.Customer.Country ascending
    select o;

Looking into it.

Frans Bouma | Lead developer LLBLGen Pro
wtijsma
User
Posts: 252
Joined: 18-Apr-2006
# Posted on: 18-Jun-2008 16:36:08   

Otis wrote:

Looking into it.

Thanks simple_smile

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 18-Jun-2008 16:46:50   

It's in relationCollection.PrepareRelations. It keeps track of aliased elements so it can check whether relations are correct or not. It uses aliased elements with their entity name, so inheritance relations are handleable too. the problem is that a derived table doesnt' have an entity name and therefore it gets a mismatch.

(The derived table on which the sort takes place is internally aliased as LPLA_L2LPLA_L2, the OrderEntity in the relation from the sorter is internally aliased as OrderEntityLPLA_L2, which don't match, but should match: it should always accept aliases with derived tables, as the correctness of the join is the reponsibility of the caller in that case. (these internal aliases are used to determine if an element isalready in the join list)

Looking into a way to fix this.

(edit) Localized one problem, but updating to the latest build of the runtime caused 1 relation to become lost, so working on that too.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 18-Jun-2008 19:29:06   

Fixed in next build (released tomorrow (thursday). (ORMSUpportclasses contains the issue and also the fixes)

Frans Bouma | Lead developer LLBLGen Pro
wtijsma
User
Posts: 252
Joined: 18-Apr-2006
# Posted on: 24-Jun-2008 15:02:56   

Otis wrote:

Fixed in next build (released tomorrow (thursday). (ORMSUpportclasses contains the issue and also the fixes)

Hi Frans,

With the new version (19th june) exactly the same code causes a different exception:


TestCase 'CC.ECDGenie.Zorg.Test.Zorgovereenkomst.ZorgovereenkomstTests.Test'
failed: SD.LLBLGen.Pro.ORMSupportClasses.ORMQueryExecutionException: An exception was caught during the execution of a retrieval query: Invalid column name 'salarisniveau_id'.. Check InnerException, QueryExecuted and Parameters of this exception to examine the cause of this exception.
    SD.LLBLGen.Pro.ORMSupportClasses.ORMQueryExecutionException: An exception was caught during the execution of a retrieval query: Invalid column name 'salarisniveau_id'.. Check InnerException, QueryExecuted and Parameters of this exception to examine the cause of this exception. ---> System.Data.SqlClient.SqlException: Invalid column name 'salarisniveau_id'.
    at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
    at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
    at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
    at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
    at System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
    at System.Data.SqlClient.SqlDataReader.get_MetaData()
    at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
    at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
    at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
    at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
    at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
    at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
    at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior)
    at SD.LLBLGen.Pro.ORMSupportClasses.RetrievalQuery.Execute(CommandBehavior behavior)
       --- End of inner exception stack trace ---
    at SD.LLBLGen.Pro.ORMSupportClasses.RetrievalQuery.Execute(CommandBehavior behavior)
    at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.ExecuteMultiRowRetrievalQuery(IRetrievalQuery queryToExecute, IEntityFactory2 entityFactory, IEntityCollection2 collectionToFill, IFieldPersistenceInfo[] fieldsPersistenceInfo, Boolean allowDuplicates, IEntityFields2 fieldsUsedForQuery)
    at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntityCollectionInternal(IEntityCollection2 collectionToFill, IRelationPredicateBucket& filterBucket, Int32 maxNumberOfItemsToReturn, ISortExpression sortClauses, ExcludeIncludeFieldsList excludedIncludedFields, Int32 pageNumber, Int32 pageSize)
    at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.FetchEntityCollection(IEntityCollection2 collectionToFill, IRelationPredicateBucket filterBucket, Int32 maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath2 prefetchPath, ExcludeIncludeFieldsList excludedIncludedFields, Int32 pageNumber, Int32 pageSize)
    D:\Projects\dotNet\Net3.5\CC.ECDGenie\MainLine\Dal\DatabaseSpecific\DataAccessAdapter.User.cs(51,0): at CC.ECDGenie.Dal.DatabaseSpecific.DataAccessAdapter.FetchEntityCollection(IEntityCollection2 collectionToFill, IRelationPredicateBucket filterBucket, Int32 maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath2 prefetchPath, ExcludeIncludeFieldsList excludedIncludedFields, Int32 pageNumber, Int32 pageSize)
    at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProvider2.ExecuteEntityProjection(QueryExpression toExecute)
    at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.ExecuteExpression(Expression handledExpression)
    at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.Execute(Expression expression)
    at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.System.Linq.IQueryProvider.Execute(Expression expression)
    at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
    D:\Projects\dotNet\Net3.5\CC.ECDGenie\MainLine\CC.ECDGenie.Zorg.Test\Zorgovereenkomst\ZorgovereenkomstTests.cs(83,0): at CC.ECDGenie.Zorg.Test.Zorgovereenkomst.ZorgovereenkomstTests.Test()

I've regenerated an included the new assemblies.

Trace information:

Generated Sql query: Query: SELECT [LPA_L1].[Id], [LPA_L1].[SalarisniveauId], [LPA_L1].[SalarisschaalId], [LPA_L1].[Kostprijs], [LPA_L1].[CreatorAccountId], [LPA_L1].[VersieStartdatum], [LPA_L1].[VersieEinddatum], [LPA_L1].[VersieNummer], [LPA_L1].[VersieObjectId] FROM ((SELECT [LPLA_1].[id] AS [Id], [LPLA_1].[salarisniveau_id] AS [SalarisniveauId], [LPLA_1].[salarisschaal_id] AS [SalarisschaalId], [LPLA_1].[kostprijs] AS [Kostprijs], [LPLA_1].[creator_account_id] AS [CreatorAccountId], [LPLA_1].[versie_startdatum] AS [VersieStartdatum], [LPLA_1].[versie_einddatum] AS [VersieEinddatum], [LPLA_1].[versie_nummer] AS [VersieNummer], [LPLA_1].[versie_object_id] AS [VersieObjectId] FROM [DEV_CC_ECDGenie].[dbo].[tb_ECDGenie_Salarisniveauschaal] [LPLA_1] ) [LPA_L1] INNER JOIN [DEV_CC_ECDGenie].[dbo].[tb_ECDGenie_Salarisniveau] [LPA_L2] ON [LPA_L2].[id]=[LPA_L1].[salarisniveau_id]) ORDER BY [LPA_L2].[code] ASC

wtijsma
User
Posts: 252
Joined: 18-Apr-2006
# Posted on: 24-Jun-2008 15:08:56   

Seems like you're creating column aliases in the sub query, but the OrderBy doesn't use the alias but the original field name...

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 24-Jun-2008 15:43:33   

Could you try the temp build attached to this post: http://www.llblgen.com/tinyforum/GotoMessage.aspx?MessageID=76236&ThreadID=13677

?

As it should contain a subquery field rename fix which is still pending for release (which popped up in edge case prefetch paths but also in your situation)

Frans Bouma | Lead developer LLBLGen Pro
wtijsma
User
Posts: 252
Joined: 18-Apr-2006
# Posted on: 24-Jun-2008 15:59:43   

Otis wrote:

Could you try the temp build attached to this post: http://www.llblgen.com/tinyforum/GotoMessage.aspx?MessageID=76236&ThreadID=13677

?

As it should contain a subquery field rename fix which is still pending for release (which popped up in edge case prefetch paths but also in your situation)

Nope, still the same error...

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 24-Jun-2008 16:18:55   

I see indeed that the query in my test shows the same issue:

SELECT [LPA_L1].[OrderId], [LPA_L1].[CustomerId], [LPA_L1].[EmployeeId], [LPA_L1].[OrderDate], [LPA_L1].[RequiredDate], [LPA_L1].[ShippedDate], [LPA_L1].[ShipVia], [LPA_L1].[Freight], [LPA_L1].[ShipName], [LPA_L1].[ShipAddress], [LPA_L1].[ShipCity], [LPA_L1].[ShipRegion], [LPA_L1].[ShipPostalCode], [LPA_L1].[ShipCountry] FROM ( ( SELECT [LPLA_1].[OrderID] AS [OrderId],** [LPLA_1].[CustomerID] AS [CustomerId], [LPLA_1].[EmployeeID] AS [EmployeeId], [LPLA_1].[OrderDate], [LPLA_1].[RequiredDate], [LPLA_1].[ShippedDate], [LPLA_1].[ShipVia], [LPLA_1].[Freight], [LPLA_1].[ShipName], [LPLA_1].[ShipAddress], [LPLA_1].[ShipCity], [LPLA_1].[ShipRegion], [LPLA_1].[ShipPostalCode], [LPLA_1].[ShipCountry] FROM [Northwind].[dbo].[Orders] [LPLA_1] ) [LPA_L1] LEFT JOIN [Northwind].[dbo].[Customers] [LPA_L2]
ON [LPA_L2].
[CustomerID]**=[LPA_L1].[CustomerID]) ORDER BY [LPA_L2].[Country] ASC

the corrector misses this predicate apparently, will see why this happens.

(edit) I think this happens because the situation is that the derived table is added first, then a normal relation is seen, and the 'OrderEntity' side is seen as already in the join list, though through a derived table. However, the ON clause is still processed as-is. As this can only happen if the derived table produces an entity, the RelationCollection.ToQueryText has to check whether the side already in the list is indeed a derived table, and if so, it should use the alias name of the field, otherwise it should use the normal field.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 24-Jun-2008 16:47:34   

Got it. I don't like code for edge cases, but there's no real other usage for this than this case, so I've added code to the RelationCollection.ToQueryTextInternal routine to handle this properly.

I've attached a new build.

Frans Bouma | Lead developer LLBLGen Pro
swallace
User
Posts: 648
Joined: 18-Aug-2003
# Posted on: 24-Jun-2008 19:32:31   

I think this happens because the situation is that the derived table is added first, then a normal relation is seen, and the 'OrderEntity' side is seen as already in the join list, though through a derived table. However, the ON clause is still processed as-is. As this can only happen if the derived table produces an entity, the RelationCollection.ToQueryText has to check whether the side already in the list is indeed a derived table, and if so, it should use the alias name of the field, otherwise it should use the normal field.

You know, seeing you produce a sentence like the above indicates it's time for you to take a very long vacation. The only way to write something like that is to have lived the code for far too many months!

stuck_out_tongue_winking_eye

wtijsma
User
Posts: 252
Joined: 18-Apr-2006
# Posted on: 25-Jun-2008 00:24:31   

swallace wrote:

I think this happens because the situation is that the derived table is added first, then a normal relation is seen, and the 'OrderEntity' side is seen as already in the join list, though through a derived table. However, the ON clause is still processed as-is. As this can only happen if the derived table produces an entity, the RelationCollection.ToQueryText has to check whether the side already in the list is indeed a derived table, and if so, it should use the alias name of the field, otherwise it should use the normal field.

You know, seeing you produce a sentence like the above indicates it's time for you to take a very long vacation. The only way to write something like that is to have lived the code for far too many months!

stuck_out_tongue_winking_eye

ey, I'm posting at 0:24 at night, I need a vacation too simple_smile

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 25-Jun-2008 09:25:12   

swallace wrote:

I think this happens because the situation is that the derived table is added first, then a normal relation is seen, and the 'OrderEntity' side is seen as already in the join list, though through a derived table. However, the ON clause is still processed as-is. As this can only happen if the derived table produces an entity, the RelationCollection.ToQueryText has to check whether the side already in the list is indeed a derived table, and if so, it should use the alias name of the field, otherwise it should use the normal field.

You know, seeing you produce a sentence like the above indicates it's time for you to take a very long vacation. The only way to write something like that is to have lived the code for far too many months!

stuck_out_tongue_winking_eye

smile

Luckily the office is close to the beach, so 10 minutes after I wrote that I was sitting in the sun, having a beer wink . But you're absolutely right, sentences like that aren't really a good sign hehe sunglasses

@Wiebe: don't take work THAT seriously, man. wink

Frans Bouma | Lead developer LLBLGen Pro