DEV Community

Cover image for I built a MyBatis-style SQL mapper for .NET because EF Core was eating all our memory
jinho von choi
jinho von choi

Posted on

I built a MyBatis-style SQL mapper for .NET because EF Core was eating all our memory

When I inherited a .NET-based stats service, the codebase was EF Core all the way down. Query performance was the first problem — and that I solved, eventually cutting response times by 2x to 3600x depending on the query. But memory was different. EF Core's change tracking, materialization overhead, and object graph behavior imposed a ceiling I couldn't optimize past.

I'd spent most of my career on Java and Spring. MyBatis was my default tool for anything SQL-heavy. I looked at Dapper — solid library, genuinely good — but I wanted SQL and code to live in separate files, not inline strings. So I built a test mapper, moved the most memory-intensive query onto it, and measured: 2–3x faster execution, 82% reduction in memory consumption.

That test became NuVatis.
What it is: a SQL mapper for .NET that generates all mapper implementation code at build time via Roslyn Source Generators. The result is zero runtime reflection, full Native AOT compatibility (.NET 8+), and an XML-to-interface mapping model that Java developers will recognize immediately.

What it isn't: a full ORM. There's no change tracking, no migration system, no LINQ query builder. You write SQL. NuVatis maps it.
Benchmark results: https://jinho-von-choi.github.io/nuvatis-sample
GitHub: https://github.com/JinHo-von-Choi/nuvatis

Top comments (0)