Hi Pablo,
sorry for the late answer. I've read your message a dozen of times and
thought about it much more than this.
I don't have answers now, but I still think that EntitySetExpressions are
TableExpressions:
- when used in lazy loading, it is a joined table, where criteria and
original table are kept somewhere in the EntitySet
- when used directly in SQL, it is also a joined table; see the following
sample

Internally and after simplification (just to keep the essential), expression
2 is translated by linq2sql to something like

SELECT [t1].*
FROM [dbo].[Employees] AS [t0]
LEFT OUTER JOIN [dbo].[Orders] AS [t1] ON [t1].[EmployeeID] =
[t0].[EmployeeID]
ORDER BY [t0].[EmployeeID], [t1].[OrderID]

I didn't implement the expression 4 to see how it is translated, but we
would probably get a similar request.

Below is your suggestion, and another I'm thinking to as an alternative.
1. Pablo: make a difference between a table and a joined table to be mapped
as an EntitySet. My problem with that is the lot of changes it would
require, and possibly some similar code with the top-level table query.
2. Alternative: we keep a table, and just add an adapter between a table
result and an EntitySet. This would allow to treat lazy loading like a
standard query, since we always have only tables.

My current question is: if we keep the second option, will a T to
EntitySet<T> adapter (the one missing to make the cast work) solve all
problems for subexpressions and prepare to lazy loading?

Tricky problem, isn't it? :)

On Sat, Sep 20, 2008 at 14:42, Pablo Iñigo Blasco <[EMAIL PROTECTED]> wrote:

>
> = Why and when I would use an EntitySetExpression? =
>
> This question is closely related with member access expressions,
> specifically with EntitySets member accesses. Here some examples:
>
> 1- Employees.Select(e=> e.LastName)
> 2- Employees.Select(e=> e.Orders)
> 3- Employees.Select(e=> e.Orders.Select(o=>o))
> 4- Employee.Select (e=> e.Orders.Select(o=>o.OrderDetails))
>
> IMO examples 1 and 3 are currently well managed
> 1- It uses ColumnExpression for translating "e.LastName"
> 3- It uses a TableExpression for translating "e.Orders" since it is
> needed for the subquery: Select(o=>o)
>
> But... what Does it happen with example 2 and 4? they are a mixture of
> 1 and 3. The key point is the return type of each query:
>
> 1- IEnumerable<string>
> 2- IEnumerable<EntitySet<Order>>
> 3- IEnumerable<Order>
> 4- IEnumerable<EntitySet<OrderDetail>>
>
> That's why examples 2nd and 4th examples belongs to the same family of
> queries.
> - 2nd and 4th examples are candidates to use lazy loading.
> - 1st and 3rd examples should be continue working as now.
>
> = example 2 vs examples 1 and 3 =
>
> Regards the member access expression:
>
> - It isn't like a ColumnExpression since it is a relation 1:n to other
> table. However it shares a thing: In lazy loading, the rendered sql
> should be something similar to a ColumnExpression, basically rendering
> the foreign-key column name.
>
> - It appear to be a Table expression, but it is different since you
> don't need a join with another table (in lazy loading) .
>
> = The current implementation =
>
> In our current implementation, 2nd and 3rd examples, both member
> access expressions are translated as a TableExpression.
> Generally TableExpression is working fine with subqueries (3rd
> example).  However it doesn't work fine with 2nd (it crashes when the
> rowObjectCreator in the QueryRunning stage is tried to be casted to
> Func<IDataRecord,MappingContext,EntitySet<Order>>. A CastException is
> thrown since the truth is that the function's type is
> Func<IDataRecord,MappingContext,Order>. TableExpression's type blame!
>
> = Again, example 2 vs examples 1 and 3 =
>
> IMO To translate the member access expression in the 2nd example as a
> TableExpression's type is conceptually wrong.
>
> TableExpression's type should be an entity type (ie: Employee) but it
> shouldn't be  an "enumeration .of an entity type" (ie:
> EntitySet<Employee>). In fact that's how it is working and that's why
> it is crashing in QueryRunning stage .
>
> Besides EntitySet member accesses (without subqueries) need particular
> code in the rowObjectCreator method where to invoke the
> EntitySet.SetSource method and assign the query. Wich query do we have
> to assign?
> As I said in the first mail, something like:
>
> Func<.., .., EntitySet<OrderDetail>>objectRowCreator =
> delegate(...,...){
> ....
>
> var EmployeeID = row.GetIntegerAt(index);
> var value = new EntitySet<Order>();
> value.SetSource(db.Orders.Where(o=>o.EmployeeID=EmployeeID)));
> ...
> return value;
> }
>
> = example 4 vs examples 1 and 3 =
>
> From my point of view 4th example is a particular case of the 2nd
> example, but the final objectRowCreator should be something like this:
>
> Func<.., .., EntitySet<*OrderDetail*>>objectRowCreator =
> delegate(...,...){
> ....
>
> var EmployeeID = row.GetIntegerAt(index);
> var value = new EntitySet<Order>();
>
> value.SetSource(db.Orders.Where(o=>o.EmployeeID=EmployeeID).*Orders.Select(o=>o.OrderDetails)*));
> ...
> return value;
> }
>
> = Then why we need an EntitySetExpression ? =
>
> 1º  The generated sql is like a column expression and not as a
> TableExpression's generated sql.
> 2º We need don't destroy and to store the  "c# compiler's original
> subquery" in the ExpressionDispatcher.Analyze stage, and use it after
> in the CompileRowCreator stage, when the rowObjectCreator is being
> created  as we have already explained above.
>
> [In 4th example we should store this expression:
> Orders.Where(o=>o.EmployeeID=EmployeeID).Orders.Select(o=>o.OrderDetails)
> ]
>
> Hope it helps.
> Nonetheless I'm not sure if I have explained the problem correctly.
>
> Regards.
>
> >
>


-- 
Pascal.

jabber/gtalk: [EMAIL PROTECTED]
msn: [EMAIL PROTECTED]

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"DbLinq" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/dblinq?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to