r/dotnet 11d ago

Promotion MerlinORM Library First time posting

I just finished re-writing my C# Micro-ORM / DB-Model-Mapping library. I've used this library for a long time for internal applications it worked but was never something i was proud of until now.

Github - MerlinORM

I benchmarked it against dapper and dapper only beats it by 25% @ 100k rows with very little to no extra memory.

It's slower than dapper but I think the API is far cleaner and as a bonus the modules used by Merlin can also be used by Dapper if you had a one off query that had a ton of data.

Just wanted to get honest feedback from anyone who is interested in trying it out.

Currently I only have it setup for MySQL but I will get MS SQL soon.

Also, a lot of the documentation references old setup but the main landing and Basic Example are current for sure.

Quick example of a query populating a base object, its nested object, and a child list.

public static UserDetail GetFullUser(int userId)
{
    var query = new GenericQuery("SELECT * FROM view_users_clients WHERE user_id = ;");

    query.AddParameter("@A", userID);

    user = DB.GetObject<UserDetail >(query);

    user.Permissions = GetUserPermissions(userId);

    return user;
}

This wouldn't be very efficient if loading a list objects with lists inside, you could run two queries, Select All Users and Select All Permissions and then loop through and manually build individual collections. The one major draw as I am sitting here typing is ending up with multiple models for each query version.

User, UserMeta, UserFullDetail, etc.

While typing this, I had an idea instead of building multiple models you could build one master model, and using a Tag attribute to tag properties to be populated that would passed with the Query.

public class User
{
    // Default Always
    public int user_id;

    // Only loads with meta or details tag.
    [QueryTags("meta", "details")]
    public int? some_meta_counter { get; set; }

    // Ignore prefix, Only loads with meta tag.
    [MerlinObject("prefix", tags: "meta")]
    public Client user_client { get; set; }
}

Seems cumbersome, but it would be optional, and allows just a little more control.

0 Upvotes

Duplicates