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