Re: Finally which ORM tool?



Jon Skeet [C# MVP] wrote:

Frans Bouma [C# MVP] <perseus.usenetNOSPAM@xxxxxxxxx> wrote:
Too much black magic which only works if you happen to want
to work in exactly the way that was anticipated. At least, that's
been my experience of it in every scenario I've seen. It does work
pretty well for displaying stuff - but making it 2-way just has so
many problems. With any luck WPF improves matters somewhat as far
as thick clients are concerned...

It's not that bad. Avoiding it has the implication that you have to
write the glue between control and object yourself, which can be
painful and buggy as well, simply because it's boring code.

Oh absolutely. The difference is that if you then need to fix
something to behave in a particular way, you can do so. I suspect
there's a nice solution waiting in the wings somewhere, but I haven't
used it yet. As I say, I have hopes for WPF...

What I've seen is that they more or less adopted the asp.net way of
databinding. So nothing really helpful, but it allows you to do
'declarative programming'... yay! :/

That's the fundamental difference and that difference is going
to cause problems, simply because the linq query object
contains a session.

Also, if you pass a variable to the query, the value the
variable has at EXECUTION time is used, not at CREATION time:

That certainly needs to be clearly understood - but I'd say it's
useful, too, in cases where you need to do the same query
multiple times but with different parameters.

Isn't that going into the red zone of 'magic programming' ? I mean,
you have a local variable, even if it's a value typed variable, and
you have a linq query and by changing the variable's value, you
manipulate the linq query IF you're executing it at that moment.

It's probably slightly "magic" at the moment. I don't think it will
be for long. Sooner or later, devs are going to have to understand
what closures really are, and how with captured variables it really
is the variable which is captured, not its value.

'Closures', now there's a word that's overloaded too many times :).
Are we talking about sets or graph paths? :)

Don't forget that it's not just LINQ to SQL we're talking about here
- this is true for LINQ to Objects as well as anywhere else you might
use an anonymous function.

True. I saw your blogpost today with the query which looked a bit
obscure to me. Sure, it's understandable if you look closely, but
that's not the point. The point is that one easily overlooks the real
specifics of the query: a human in general has a hard time grasping any
form of computer language, simply because the human has to interpret
the code before understanding what it REALLY does.

Making it more obscure than clear doesn't really help the human
reading the code, which directly implies the chance for more bugs.

Captured variables always need to be handled with care, and I can
see that it could well trip up novices, but I don't think it's
unreasonable.

Sure, but the code LOOKS the same as:
int foo = GetFoo();
bool b = (bar == foo);

b isn't suddenly affected if foo is changed after this. Though if
I do: var q = from x in metadata.SomeEntity
where x.Foo == foo
select x;

q is affected if I change foo AFTER this query and BEFORE execution.
Why is this comparison expression suddenly different from the
expression of b? The first is executed at that moment, the latter is
executed somewhere later, but you have to follow q to found out
when. That SHOULDN'T be important, simply because q LOOKS like a
declaration, constructed at the spot where q is declared.

And it is a declaration, but one which captures the variables. I
really don't think it's that bad, once you get used to it - it's very
similar to the whole "passing a reference type argument by value
doesn't mean all the data is copied, just the reference". Once you
accept where changes will be reflected, it's quite easy to work with
that.

Though it's a way to make things really complicated without a lot of
effort, or better: you somewhat have to PUT IN effort to make it very
clear. Perhaps not for the person who wrote the code and who has spend
weeks designing and writing it, but for the poor sods who have to read
the code after the genius left for another job.

So the query isn't a query definition alone, it's also the
resultset.

No, the query itself is a query definition alone. It's only the
enumerator you get when you call GetEnumerator() which relates to
the result set.

It's an IEnumerable<T>, and therefore a resultset. If it would be a
definition alone, the queries of CHOPS would have been fetched,
simply because the declaration construction was with 'CHOPS'.

I don't see the logic in your first definition. Suppose it didn't
implement IEnumerable<T> but had an Execute() method which gave back
an IEnumerator<T> instead - in other words, we just changed a method
name and in doing so removed an interface implementation. How can
that change whether the object is itself a resultset or not? Or would
it still be a resultset in your view?

Because it implements IEnumerable, it by itself is an enumerable
resource. This IMHO implies that it's a set.

If it had an Execute method (some o/r mappers add that method), the
thing still is that it's not a declaration alone. You can't execute a
declaration without the executor who interprets the query so it gets
executed.

With Linq they placed the executor inside the declaration. Why, I have
no idea, the only guess I have is that it's 'easier' for some people
who have no clue what they're doing anyway, but then again, these
people will have a hard time with some areas of linq anyway so why
bother introducing this 'feature' for them.

The analogy is a simple SQL string: you can't execute it without a SQL
engine. To use it as a metaphore here, this is the same as linq:
string query = "SELECT * FROM Customers WHERE Country='USA'";

foreach(var customer in query)
{
// do something with customer
}

Everyone will say: "you can't execute a string". No of course you
can't, as it contains the declaration of a query. You need an execution
engine to execute the query. That would have been better IMHO, because
it separates declaration from execution, which are combined in a linq
query.

The query itself doesn't contain the data, it simply contains all the
information required to fetch the data. That doesn't make it a
resultset in my view. It's all a matter of definition though.

Something which is enumerable, isn't that semantically a sequence, a
set for you?

Because the linq query isn't a declaration alone, you can't do things
with it like pass it to an execution engine of choice, you have to
execute it with the engine inside the query, or you have to be lucky to
be using a linq provider which gives you this flexibility ;).

I've always found the deferred execution very natural, both in
LINQ and Hibernate - I create a query, do other things if
necessary, and then use the query when I'm ready. Why should
creating the query execute it immediately?

No, that's not what I meant. What I meant was: you declare a query
somewhere, e.g. in a method you call to formulate the query, then
execute it somewhere else, however the query declaration is already
fixed, so you can alter it, by changing a parameter on a predicate,
but not by changing a local variable's value.

The fact that the execution doesn't happen at the declaration means
it's deferred execution by every other use of the phrase that I've
ever seen.

You're using "deferred execution" to mean what I'd probably describe
as "deferred parameter evaluation". It's an interesting topic to talk
about, but I'd prefer it if we didn't keep calling it "deferred
execution".

Sure, I don't like word-games, so I don't mind. The thing is though
that I find it very important that people understand that the place
where the executor is located in a linq query is an important issue,
and not something you can simply wave away as 'not that important'. The
thing is that it severily limits the user of the framework in how s/he
wants to use the query, while it doesn't give the user any real
benefits, except perhaps the 1 line of code they don't have to type now.

Now, you also bring up another topic: separating the query from its
data connection. You can't easily separate it from its whole data
context in terms of the types involved, because at that point you
lose a lot of the benefits of LINQ - but I could certainly envisage
separating it from a "live" context. I don't know what LINQ to
Entities will have, but I wouldn't be at all surprised to see that in
there.

Depends on if they still move ahead towards a multi-db design. I have
the feeling they won't, as it could give their competitors in the DB
market the same advantage SqlServer will have now (as IBM and Oracle
have already made their DB engines capable of running these kind of
engines in-process so it won't be hard for them to move an EDM layer
into their databases, IMHO).

FB
--
------------------------------------------------------------------------
Lead developer of LLBLGen Pro, the productive O/R mapper for .NET
LLBLGen Pro website: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------
.



Relevant Pages

  • Re: Finally which ORM tool?
    ... the session' method. ... they use the same mechanism as Linq to Sql does: ... Also, if you pass a variable to the query, the value the variable ... q is affected if I change foo AFTER this query and BEFORE execution. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Finally which ORM tool?
    ... the session' method. ... able to execute the query by itself. ... has at EXECUTION time is used, ... That SHOULDN'T be important, simply because q LOOKS like a declaration, ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Finally which ORM tool?
    ... manipulate the linq query IF you're executing it at that moment. ... simply because the declaration construction was with 'CHOPS'. ... implement IEnumerablebut had an Execute() method which gave back ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Discussion: linq vs stored procedures
    ... My experience with linq is that I can develop my web application very fast. ... I have read that using stored procedures are executing faster. ... The advantage of stored procedures is that you are sure that the query always looks the same, so the database will cache the execution plan and the result. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Finally which ORM tool?
    ... you manipulate the linq query IF you're ... implement IEnumerablebut had an Execute() method which gave ... Every Linq provider will implement ...
    (microsoft.public.dotnet.languages.csharp)