I will only talk about the last part here. A subquery is a "joined table": - when running as a complex expression and eager loading (), it will generate subselects, joins, and so on. Not our problem yet. - when running as lazy loading, it becomes what you say: a new IQueryable with a where expression on the related entity (the where being the FK).
I'd like to give it a try, knowing that the solution won't work the same in MONO_STRICT mode (since in strict mode, an EntitySet is not an IQueryable, so it would force loading, except if we find a hack, and I think we can). If you agree, I will prototype an EntitySet referencing the entity, and generating a query upon it. This would also solve the complex subqueries. On Fri, Sep 26, 2008 at 11:44, Pablo Iñigo Blasco <[EMAIL PROTECTED]> wrote: > > 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. > > > > -- 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 -~----------~----~----~----~------~----~------~--~---
