Earlier quoted context omitted.
I'd kill for anything close to EF for Node. Selecting complex structures from a database in any of the existing JS ORMs is just painful.
Mikro ORM is the best I had come across while avoiding Prisma.
Understanding the .NET ecosystem: The evolution of .NET into .NET 7
261–270 of 357 posts
Re: Understanding the .NET ecosystem: The evolution of .NET into .NET 7
#262Earlier quoted context omitted.
I've enjoyed the ORM in adonisjs: https://docs.adonisjs.com/guides/models/relationships#preloa... Having used it on an actual product and dealing with some of the pain points, it's my go-to since the typescript version (v5) came out. The ORM uses Knex.js internally, which is very simple to drop into if you just want a query builder. Having Knex be accessible also makes it simple to just write your query in plain sql…
These are more akin to Dapper which is a thin layer on top of SQL. Currently I use Prisma for JS, it's a bit better, but if you haven't used EF then you probably don't know what you're missing.
Which features would you say are the key ones that make Lucid seem more like a query mapper (Dapper, Knex) than an ORM (ActiveRecord, EF)?
Specifically, in my Adonis projects, I'm mostly working with the Model objects through the ORM methods, and only dropping to Knex/SQL when necessary (complex CTE, etc). Since it's such a Model-centric seeming way of development, it naturally seems like an Object-Relational Mapping to me.
Re: Understanding the .NET ecosystem: The evolution of .NET into .NET 7
#263Earlier quoted context omitted.
> ORM? EF Core is pretty good. We're moving to .Net, and I was surprised by how poor the built-in DB stuff is. It's like either assembly or Python, but nothing in the middle. That said I've also been impressed about how nice it is to get stuff going. I used C# back in the .Net 1.1 days and yeah massive difference in ergonomics.
>We're moving to .Net, and I was surprised by how poor the built-in DB stuff is Right now EF Core is probably the best ORM that has ever existed. What exactly is missing? Although for performance you would probably reach for something like Dapper but that is not an ORM.
* Support for "FOR UPDATE" and "SKIP LOCKED"; it's easy enough to tag the queries and modify the SQL in an interceptor though.. Yuck.
* Transaction attributes ala Spring; Though I can make do without them it's nice being able to specify what sorta transaction party a method is interested in.
* Better support for "bulk updates". SQL Alchemy, as rough an onboarding experience as it is, has really good support for executing db-side update logic.
That said, I largely agree with you and nobody should overlook LinqPad. Anyone interested in babysitting the generated SQL should be using it; too bad it's not on Linux :| :( ;(
The optimizations they cover in the docs should all be done by default IMHO; optimizing models, polling db contexts, and etc. I also open and close a db connection at app start which further reduced the first request latency after putting a process in rotation.
Re: Understanding the .NET ecosystem: The evolution of .NET into .NET 7
#264Earlier quoted context omitted.
> Right now EF Core is probably the best ORM that has ever existed. What exactly is missing? Wish I could agree but they would have to fix the very slow time to first query when using big models (+500 tables in our case). Compiled models is not a solution for us since our model changes a lot and the compilation is just as slow. It's disappointing because it used to work fine under the ancient Linq2SQL library.
Can't you generate the compiled model as part of the CI/CD? Also maybe you might find a benefit from splitting your context into multiples. I am considering this option for one of my code bases
Re: Understanding the .NET ecosystem: The evolution of .NET into .NET 7
#265Earlier quoted context omitted.
Configuration is applied in layers. If you’re using the default setup you get the following layers applied in this order: 1. appsettings.json 2. appsettings.{env}.json 3. user secrets (only in Development environment) 4. environment variables 5. command line args You can full customize the setup if you desire, there are packages to support things like external secret stores. If you Google ‘Asp.Net core configuration”…
Awesome overview, stuff like this is often hard for newcomers to find/figure out. I'm sure it's in the docs somewhere but people often miss it. One nitpick: environment vars don't have to be capitalized. You can do ConnectionStrings__MyConnection so the casing matches what you see in appsettings.json. And a word of warning: make sure to understand how the configuration overrides work. If you have appsettings.json def…
Re: Understanding the .NET ecosystem: The evolution of .NET into .NET 7
#266Earlier quoted context omitted.
These are more akin to Dapper which is a thin layer on top of SQL. Currently I use Prisma for JS, it's a bit better, but if you haven't used EF then you probably don't know what you're missing.
I've used EF quite a bit in the past. While there may be some features missing, Lucid an ActiveRecord implementation, which I would figure would fall into the "ORM" category. Which features would you say are the key ones that make Lucid seem more like a query mapper (Dapper, Knex) than an ORM (ActiveRecord, EF)? Specifically, in my Adonis projects, I'm mostly working with the Model objects through the ORM methods, an…
Selecting complex dtos, this isn’t query building. A lot of magic turns this into sql.
TopPaidMayors = Cities
.where(c => c.state.govoner.party ==‘dem’)
.select(c =>
c.name,
highestPaid = c.mayors
.orderByDesc(m => salary)
.take(10))
.orderBy(c => highestPaid.First().salary)Re: Understanding the .NET ecosystem: The evolution of .NET into .NET 7
#267.NET has been doing a lot of things right. My startup's codebase is nearly all .NET 7: landing page, web app, Windows service, API. The main non-.NET code is vanilla JS in the web app. I've been keeping a close eye on Next.js, which is very well done, but I love how versatile .NET is. With one language, I can write all of the above, and my dependencies are minimal thanks to .NET's rich standard library - a refreshing…
Using Asp.Net 7 for the server component with React and Vite as the FE tooling. Been a HUGE learning curve the first couple months particularly around the DI, options pattern, Asp.Net auth and Identity and etc but everything is falling into place now. Also SignalR is much more low-level than it pretends to be lol.
It would have been easier to go straight NodeJS as I'm quite proficient in writing even framework level code in it(down to the sockets), but I believe .Net is the better option for this long term.
Re: Understanding the .NET ecosystem: The evolution of .NET into .NET 7
#268Earlier quoted context omitted.
I stuck to DB-First model + LINQ + SaveChanges() and largely managed to keep out the magic quite successfully for a .NET6 web project last year. Records are fantastic when composing queries. I didn't touch inheritance or any fancy mapping strategies -- one table, one class. The only bit of framework-specific / hidden magic debugging I really had to do was the realization of AsSplitQuery() when creating objects compos…
Yeah, if you stick to a very narrow subset of what it can do then you will have no problems. Hopefully everyone else on your project is on the same page about what that subset is.
I don’t know why one would have an issue with not using the features they’re not looking for anyways. Keeping everyone aligned on patterns/usage is half the point of code review, and it was managed there without much trouble (you can’t really do the truly magical incantations without quite a bit of setup)
Re: Understanding the .NET ecosystem: The evolution of .NET into .NET 7
#269Earlier quoted context omitted.
Right, marking methods as virtual is the other route I saw. Are most C# codebases opting to do that rather than add interfaces? It feels weird to edit signatures like that for testability, but maybe it's just what I'm used to - I'm putting all of my objects in constructors already for testability's sake, and I'm no stranger to making a factory or two. VSCode has been my way forward for file-based editing so far. It's…
That is a good question. I'm not sure. I've seen a lot interface usage for testing web apps or backend services at companies when I was doing consulting work. I personally use stubs for higher reuse, favor integration/functional tests over units, and InternalsVisibleToAttribute to allow the use of internal classes / methods from test assemblies. Its been a long while since I reached for a mocking library. I probably…
Mocking leads to “interfaces everywhere”, I agree. The latter also results from the attitude of putting interfaces all over, even if there’s just a single concrete implementation that makes sense at any point in time, like a file hashing routine (which of course should just be a function but that’s not a thing in C#). Dependency inversion gone overboard?
My biggest qualm with mocking is setting up a detailed test, where every method called is specified, alongside their order etc. You’re reimplementing the entire method essentially. Those tests I despise.
Re: Understanding the .NET ecosystem: The evolution of .NET into .NET 7
#270Earlier quoted context omitted.
There are other libraries than Moq. Nsubstitute, FakeItEasy, etc. With Moq and most mocking libraries, you generally just need to make a method virtual for mocking concrete classes. Most mocking libraries use Castle Project's Dynamic Proxy, so they should be able to inject things without the need of interfaces. Interfaces for everything comes from the .net community's obsession with patterns, abstraction, clean archi…
Right, marking methods as virtual is the other route I saw. Are most C# codebases opting to do that rather than add interfaces? It feels weird to edit signatures like that for testability, but maybe it's just what I'm used to - I'm putting all of my objects in constructors already for testability's sake, and I'm no stranger to making a factory or two. VSCode has been my way forward for file-based editing so far. It's…
There are other practical reasons for using interfaces other than just "patterns" and "testing" though. Perf is one; you can avoid a lot of unnecessary mapping by being able to pass concrete types between modules when the receiver is accepting a shape instead of a concrete type...