A full port of LINQ for JavaScript
github.com
github.com
This would be pretty useful in ES7 or whatever spec is coming down the road for javascript.
Abstractions will add stuff on top of that which doesn't necessarily pay its own rent in benefits.
call method -> execute SQL statement
If you're sticking something that implements IQueryable<T> in there, then it becomes: call method -> execute LINQ query -> compile to SQL statement -> execute SQL statement
I've found that those two extra steps in the middle typically add negative net value.They don't really make the code more readable; LINQ is so close to basic SQL that I can't fathom how a developer who can learn to write LINQ queries wouldn't be able to grok SQL.
They cut you off from the full power of the database by limiting you to a sort of least common denominator version of the things you can do with real SQL (e.g., no PIVOT or MERGE if you're using mssql).
They make the code harder to properly understand, because it's not readily apparent what will execute on the database. Some expressions will compile to SQL, some will execute in code, and some will execute in code and also force a bunch of other stuff that might have been compilable to SQL to execute in code instead.
They will probably remove some boilerplate, but you can just as easily remove that boilerplate with a too like Dapper that doesn't come with all those other downsides.
Even without the use of other backends it may still be beneficial. The "abstraction layer" need not to be thin as you explained here. You have the power to reinterpret and optimize your query. This allows visitor patterns (and maybe Roslyn-style analyzers) to kick in in the symbolic form, not just strings (indeed there's SQL parser, but again why? why limit it to SQL?)
I find statements like this statement are the crux differentiator of whether or not you find IQueryable<T> to be a useful abstraction or not. If you think LINQ is some unfathomable black box that magically, and with little observable difference, spits out SQL and/or executes code then of course you are going to have a bad time.
In my time doing LINQ performance work, I've had some ideas on how to make the tooling better (ToList() considered harmful, there could be stronger highlighting of "monad transitions" especially IQueryable<T> to (accidental) IEnumerable<T> and/or (intentional and mistaken) IList<T>), but all the information is already there in the tooling for the most part. It's not a black box, you can query a lot of information with tooltips alone.
LINQ really shines in places where you've got one "query" that runs on multiple databases and multiple types of databases, with no code change but a connection string or three.
Those transitions between monads can be a headache to an inexperienced developer and a delightful tool in experienced hands. There is a huge benefit that the "same query" can run on database with IQueryable<T> and also in memory with IEnumerable<T>, are interesting ways to take advantage of that, reusing code that can work both with fresh data directly on the database and with cached data already in memory as if it were the same data. There are amazing strengths to that abstraction.
There is also no doubt that it all has a steep learning curve.
The nice part about using Linq and IQueryable instead of e.g. query strings, is that the compiler (and intellisense) can check for some errors at compile-time instead of run-time. Just have to make sure your database model is 1:1 with the actual database.
After you have the data you can throw it into a non-database DTO to re-couple a bit and pass it between layers.
In non-trivial applications this is where you get the best performance bang for your buck. ORMs are convenient dev tools, but I don’t see them as real options for deploying real apps of any meaningful scale.
Being able to write decent unit test suites is one of the biggest things that moved me from inline SQL back toward sprocs.
https://msdn.microsoft.com/en-us/library/dn314429(v=vs.113)....
It's faster, in memory and multiple people can test simultaneously without contention issues. I've done the whole wrap sql tests in a transaction thing, it was slow and wrought with database locks.
The added advantage is that if you do it right. You not only can switch between different RDMSs you can switch to anything that has a Linq provider. I have a mix of SQL Server and Mongo and the clients don't know the difference they just pass in Expression like (e => e.Id && e.salary > 50000) and it gets translated at runtime to either MongoQuery or Sql. I've switch between the two and they never knew the difference - just update a nuget package.
There are a couple different ways you can set it up to use the actual database to do this, thereby eliminating the extra work of having to maintain two different copies of your schema in two different languages, and making sure they're kept in sync.
You might be interested in Rezoom.SQL [1], which is exactly the thing you describe.
As an aside, it also has unusually thorough documentation [2] by F# standards.
See quicktype, for example, which supports a lot of languages.
This isn't built in to the editor, but can be run from the command line. A benefit is that it does not suffer from the other problems with type providers, like not supporting the full language, (e.g., records and discriminated unions in F#).
Slightly more convenient for one source becomes very convenient as the amount of data your analyzing increases. It's not the be-all-end-all it was promised to be as a feature but it is easier than code generation IMO. If you can get rid of the disadvantages by keeping reference schema locally in its native form (e.g no flakiness you mention) then why not use it?
You can write your repository with a method signature like this....
Find(<Expression<Func<Employee,bool>> query) {....}
With Employee being a regular old undecorated POCO.
Then if you call it:
Find(e => e.id == 5)
The repository can be searching for data in a SQL Server database using Entity Framework or a Mongo database using the Mongo driver or even an in memory list for unit testing and the calling code doesn't care.
Yes the expression will be translated to the appropriate query (MongoQuery or SQL) without any coupling.
You return a List<Employee> not an IQueryable.
It additionally has the benefits of ESNext (Stage 3) AsyncIterable support, and some synergy with RxJS.