3 ms·
LINQ in EntityFramework certainly isn't perfect, but frankly it's so far ahead of anything else available in all other languages. It was a brilliant idea to add
by fireant 2y ago
LINQ in EntityFramework certainly isn't perfect, but frankly it's so far ahead of anything else available in all other languages. It was a brilliant idea to add expressions type into the language AND to create a standard set of interfaces that enable collection interop AND to to then create universal clients for local and remote collections that use all this machinery to deliver first class DX.
- int_19h 2y ago"All other languages" is a stretch IMO. Any language that has proper macros (e.g. Rust, Clojure) can do something LINQ-like as well as C#.
- CharlieDigital 2y agoCan you post some examples? Having been working in TS with Prisma for a bit, what stands out is how a Prisma query is effectively trying to express an expression tree in structural form An example on TS with Prisma: const loadedAda2 = await tx.runner.findFirst({ where: { email: 'ada@example.org' }, include: { races: { where: { AND: [ { position: { lte: 10 } }, { time: { lte: 120 } }, { race: { name: { contains: 'New' } } } ] } } } }) (Other query tools like Kysely end up using strings (though with the support of TypeScript at dev time)) And the same in C# with EF and LINQ: var loadedAda = await db.Runners .Include(r => r.RaceResults.Where( finish => finish.Position <= 10 && finish.Time <= TimeSpan.FromHours(2) && finish.Race.Name.Contains("New") ) ) .FirstAsync(r => r.Email == "ada@example.org"); The difference being that the C# code is actually passing an expression tree and the code itself is not evaluated, allowing C# to read the code and convert it to SQL.
- int_19h 2y agoTS does not have macro facilities. Proper macros operate on AST, which it to say, it is exactly like the Expression stuff in C#, except it can represent the entirety of the language instead of some subset of it (C# doesn't even fully support the entirety of System.Linq.Expressions - e.g. if you want LoopExpression, you have to spell the tree out explicitly itself).
- CharlieDigital 2y ago> TS does not have macro facilities That I'm aware; I'm curious how this works on Go or Rust.
- int_19h 2y agoFor details, take a look at the examples here: https://doc.rust-lang.org/book/ch20-06-macros.html https://doc.rust-lang.org/book/ch20-06-macros.html For procedural macros, what you get is not even the syntax tree but rather the token tree: https://doc.rust-lang.org/proc_macro/struct.TokenStream.html https://doc.rust-lang.org/proc_macro/struct.TokenStream.html. You can then use stdlib to parse that into a Rust syntax tree (which is roughly the equivalent of Expression): https://docs.rs/syn/latest/syn/enum.Expr.html https://docs.rs/syn/latest/syn/enum.Expr.html Or you can do your own parsing, meaning that you can handle pretty much any syntax that can be lexed as Rust tokens. Which means that e.g. the C# LINQ syntactic sugar (from ... select ... where etc) can also be implemented as a macro. Or you could handle raw SQL and do typechecking on it.