Hi Pascal!

On Mon, Sep 22, 2008 at 11:11 PM, Pascal Craponne <[EMAIL PROTECTED]> wrote:
> 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' m late too, hence sorry too :-). Hehe, I'm sure that you are very
busy and you have got a lot of responsibilities, therefore, anyway,
thanks for your time and effort!

> 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 think we are mixing implementation ideas.
Above in this thread we was discussing about two implementations:
A - using lazy loading, presumably easier to implement though slower.
B - "complex loading?" where only one sql sentence is executed and the
object tree is rebuilt.

[I'm not sure with this but: I also make a difference between "complex
loading?" and "eager loading". IMO "eager loading" is a "complex
loading" using LoadOptions. ie: Linq2sql implements "complex loading?"
but not "eager loading". do you agree? any clarification here?]

Anyway, I am thinking only in A, at least by the moment and I don't
see why some TableExpression can be replaced. I'll talk more about it
below.

Linq2sql uses B and he given sample uses B.
It's curious because in this sample linq2sql doesn't use an auxiliar
column (like the first post sql-sample) for rebuilding the tree
(IEnumerable<EntitySet<Order>>). How does it split the returned
orders? Surely using the EmployeeID column.

Yes it seems a good method and it should be our target.

 It doesn't seem hard to implement something for solving this example
in Dblinq since the linq2sql's generated sql is the same than ours. We
could implement something for rebuilding the object tree in the
query-running stage. Yes, but that means that we would be implementing
the B option directly.

IMO, To front the B implementation directly would be hard probably,
When I see the 4th example and a lot of clouds invade my mind, and we
have already discussed a bit about this complexity.

What about A?

The spirit of A could be defined like "divide and conquer":
Doesn't matter how complex is an expression, divide it in a set of
simpler expressions.

example:
db.Employees.Select(e=>e.Orders) [Not yet supported]
would be divided in a lot of
db.Orders.Where(o=>o.IdEmployee==constant) [Supported]

At first place here I don't agree (by the moment) with this:

> - when used in lazy loading, it is a joined table, where criteria and
> original table are kept somewhere in the EntitySet

Let's to see a few examples:
* db.Employees.Where(e=>e.Orders.Count()>0)  ->  e.Employee should be
a TableExpression and a join is needed
* db.Employees.Select(e=>e.Orders.Select(o=>o.orderID)) -> e.Order
should be a TableExpression and a join is needed
* db.Employees.Select(e=>e.Orders.Count()) -> e.Order should be a
TableExpression and a join is needed

* db.Employees.Select(e=>e.Orders) -> (example 2)  IMO a join is not
needed.  Using lazy loading the generated sql should be something
like:

SELECT [t0].[EmployeeID]
FROM [dbo].[Employees] AS [t0]

* db.Employees.Select (e=> e.Orders.Select(o=>o.OrderDetails)) ->
(example 4)  IMO a join is not needed. Using lazy loading the
generated sql should be something like:

SELECT [t0].[EmployeeID]
FROM [dbo].[Employees] AS [t0]  -> yeah, the same than the above sample.

Doesn't matter how complex is the subexpression in the select
expression. If the type is EntityType<X> we apply "divide and
conquer".

*  db.Employees.Where(e=> e.Orders.Count()>3).Select (e=>
e.Orders.Select(o=>o.OrderDetails)) -> IMO e.Orders in the Where needs
a TableExpression and a join, but e.Orders in select doesn't need to
be a TableExpression.
It should be translated as:

SELECT [t0].[EmployeeID]
FROM [dbo].[Employees] AS [t0]
WHERE ( SELECT Count([t1].[OrderID]) FROM [dbo].[Orders] as [t0] WHERE
[t0].[EmployeeID] = [t1].[EmployeeID]) > 3

> 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.

You know all the engine much better than me, so probably I'm wrong.
However I still only see changes in
ExpressionDispatcher.AnalyzeMemberAccess and also some changes in
CompileRowCreator stage (for generating a more suitable
objectRowCreator method to set queries into entitySets)

> 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.

I think that I don't understand it. It would be interesting if you
extend more this idea. What do you refer with an adapter? I currently
see an EntitySet object which has a reference to one object: to the
original query? a reference to the raw data results?

> 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? :)
yeah ^_^

Regards.

--~--~---------~--~----~------------~-------~--~----~
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