From: Mikeon on
> ok, though unnecessary actions don't learn you anything unless you
> realize the abstraction was unnecessary.

I must disagree. Or at least comment on that. It is hard to define
"unnecessary". Can you even say if something is unnecessary if its
goal is to learn?
We have closed circle here :-)

> > repository.Get(delegate(User usr) { return usr.Name == "John"; });
>
> err, isn't that simply resulting in
> SELECT ... FROM User WHERE Name = @name
>
> so @name = "John" ?

Yes for SQL it is exactly what you say, but there are few problems.
In order to make this easy to translate, you would have to write
something like
"Name" == "John"

This is not something a compiler will help you with in case of errors.
Suppose you write "Nane" instead. What you get is runtime exception.
usr.Name is far more cleaner and safer.

> any o/r mapper will issue a select with a where in that case, unless
> you meant something different.

But none can translate a "safe" statement such as usr.Name == "John"
to an SQL query.

> > LINQ makes this easier of course. I suppose mappers usually use some
> > kind of "hack" i.e. code generation to do it.
>
> Linq is a way to formulate queries, so just a different way of
> formulating the query than you would in the o/r mapper's native query
> language.

Linq as far as I know gives you a way to formulate query in a "safe"
way like usr.Name == "John" and thanks to the fact that compiler knows
about Linq it translates your "safe" query to an expression tree -
which are more or less Query Object that can be used by o/r mappers.
Expression tree has information about what kind of operator was used,
what were the operands etc. You don't have this information when you
write usr.Name == "John" without a Linq support.

> So you're more looking for a generic wrapper for all o/r mappers out
> there? Good luck ;)

Its not my goal, but yes you could say, that it will be the outcome of
my learning process. I will only have to provide a translation layer
that translates my Specification objects to o/r mapper native Query/
Criteria objects and it should work.
Is it so hard to imagine such a situation? Aren't o/r mappers dealing
with all relational databases out there already? Why would you think
it is impossible on a higher level?

--
Michal

From: Frans Bouma on
Mikeon wrote:

> > ok, though unnecessary actions don't learn you anything
> > unless you realize the abstraction was unnecessary.
>
> I must disagree. Or at least comment on that. It is hard to define
> "unnecessary". Can you even say if something is unnecessary if its
> goal is to learn?

Do you learn anything if the goal you achieve isn't based on solid
ground, besides how to waste time in a proper manner? ;)

> > > repository.Get(delegate(User usr) { return usr.Name == "John"; });
> >
> > err, isn't that simply resulting in
> > SELECT ... FROM User WHERE Name = @name
> >
> > so @name = "John" ?
>
> Yes for SQL it is exactly what you say, but there are few problems.
> In order to make this easy to translate, you would have to write
> something like
> "Name" == "John"
>
> This is not something a compiler will help you with in case of errors.
> Suppose you write "Nane" instead. What you get is runtime exception.
> usr.Name is far more cleaner and safer.
> > any o/r mapper will issue a select with a where in that
> > case, unless you meant something different.
>
> But none can translate a "safe" statement such as usr.Name == "John"
> to an SQL query.

Sure it can. I can:

UserEntity u = null;
using(DataAccessAdapter adapter = new DataAccessAdapter())
{
u = (UserEntity)adapter.FetchNewEntity(new UserEntityFactory(),
new RelationPredicateBucket(UserFields.Name=="John"));
}

keyword: 'operator overloading' :)

Our query system is completely type safe and compiletime checked.

> > > LINQ makes this easier of course. I suppose mappers usually use
> > > some kind of "hack" i.e. code generation to do it.
> >
> > Linq is a way to formulate queries, so just a different way
> > of formulating the query than you would in the o/r mapper's native
> > query language.
>
> Linq as far as I know gives you a way to formulate query in a "safe"
> way like usr.Name == "John" and thanks to the fact that compiler knows
> about Linq it translates your "safe" query to an expression tree -
> which are more or less Query Object that can be used by o/r mappers.

besides the fact that you can have safe query methods today, the
expression tree isn't like a query object. I wish it was... The tree is
somewhat cumbersome to parse, as it needs a lot of switch/cases.

It's also possible to implement linq support without IQueryable
though, by using extension methods.

> Expression tree has information about what kind of operator was used,
> what were the operands etc. You don't have this information when you
> write usr.Name == "John" without a Linq support.

I do actually, but you're correct, the expression tree has this too. :)

> > So you're more looking for a generic wrapper for all o/r
> > mappers out there? Good luck ;)
>
> Its not my goal, but yes you could say, that it will be the outcome of
> my learning process. I will only have to provide a translation layer
> that translates my Specification objects to o/r mapper native Query/
> Criteria objects and it should work.
> Is it so hard to imagine such a situation? Aren't o/r mappers dealing
> with all relational databases out there already? Why would you think
> it is impossible on a higher level?

Because every o/r mapper out there uses its own standard how to query
entities, and these are often not that compatible.

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#)
------------------------------------------------------------------------