On Mon, 2009-10-12 at 11:29 +0200, Giacomo Tesio wrote:
> I'm taken over a different part of our "big enterprise project", so I
> couldn't work for dblinq in the last 2 months...

Been there, done that, released MonoTouch.

Theoretically I'm back on DbLinq full-time now, but I'm occasionally
pulled back into MonoTouch-land...

> Instance methods (and likely full closures) aren't supported because they use
> parameters which don't exist within the DbLinq-generated expression tree.
>
> What did you mean about closures?

The comment is wrong, as is noted by the r1229 commit.  Regardless, in
this context a closure would be a variable that needs to have "things"
done to it by the compiler.

Commit r1229 is a perfect example:

        var s = "param";
        var q = from e in db.Employees select new {
                InstanceName = GetInstanceName(e, s, "constant"),
        };

In this case, 's' is a local variable which is being used as part of the
GetInstanceName() method invocation, so the compiler needs to create a
closure which "captures" 's' so that it's usable from the expression
tree.

Suffice it to say, I was somewhat confused at this time
because .ToList() wasn't working while other methods were.

I've now figured out wtf was wrong.  The fix...is another matter.

So the problem is that EntitySet<T>'s are not properly supported.  For
example, this works:

        var q = from e in db.Employees select e;
        foreach (var e in q)
                Console.WriteLine(e.Orders.Count);

So we're only using Employee.Orders, which is an EntitySet<Order>.

However, this fails:

        var q = from e in db.Employees select new {e.Orders};

In fact, trying to access ~any EntitySet<T> member within the 'select'
expression pretty much bombs things.  There was apparently some form of
support in ExpressionDispatcher.Analyzer.cs, i.e. if we uncomment line
835 so that it's:

        if (!isEntitySet)

we remove one runtime exception...and get another because the SQL we
generate is horribly, hilariously, wrong.

The fundamental problem here seems to be that we do EntitySet<T> support
at the wrong time -- in the above working case, e.Orders is instantiated
(and made useful) within DataSet.SetEntitySetsQueries() (which is called
as part of entity registration).  This is FAR too late to be useful
within the select expression (as it executes after the select expression
has executed).

Once the EntitySet<T> issue has been fixed, using extension methods
should Just Work (including .ToList()).

I'm pondering ways to move the DataSet logic into EntitySetExpression...

In other vaguely related news, the fix in r1228 is far from ideal.  It
works in that it allows valid code to behave properly, but it can result
in multiple object instantiations -- for example:

        var q = from e in db.Employees select new {
                Foo = Foo(e),
                Bar = Bar(e),
                Baz = Baz(e)
        };

The above will result in instantiating an Employee instance for EACH
method call within the 'select' expression.  Perhaps this is desirable,
perhaps not -- I have no idea what the L2SQL semantics are here, we'd
need to test it -- but I doubt that it's desirable.

 - Jon



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