eko
eko

Reputation: 389

.NET Dapper - Mapping computed properties

I'm using Dapper for handling database connection in a .NET project. The automatic column mapping works well and I can also map columns to different property names in the model. However, how can I map computed properties? For example, my model is

class User
{
    public int Id {get; set;}
    public string Name {get; set;}
    public bool IsPremiumUser {get; set;}
}

And the table is

Id | Name | CreationDate | IsPremiumUser

Now, IsPremiumUser can be null in db but not in the model. I'd like it to be mapped by the following logic:

if (row.IsPremiumUser != null)
{
    model.IsPremiumUser = row.IsPremiumUser;
}
else
{
    model.IsPremiumUser = row.CreationDate < 1.1.2000;
}

In other words, its value depends on 2 columns. Also there are multiple cases where I'd like to set a boolean property based on if a certain relationship exists. How to handle these more complex mapping cases?

Upvotes: 0

Views: 2276

Answers (2)

Void Ray
Void Ray

Reputation: 10209

Another option is to make a factory and let it assemble the user:

var userRecords = _connection.Query<UserRecord>("select * from users");   
var users = UserFactory.Build(userRecords);
  • UserRecord class is only used to query the data
  • Factory will handle property mapping and dynamic properties

Pros: Keep SQL queries free of logic. Factory is more flexible over time.

Cons: More code

Upvotes: 0

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236218

Just use SQL query which will check if IsPremiumUser field not null and return result of creation date check if user does not have this flag set:

var sql =
    @"SELECT 
        Id,
        Name,
        CASE
            WHEN IsPremiumUser IS NOT NULL
                THEN IsPremiumUser
                ELSE CAST(CASE WHEN CreationDate < '2000-01-01' THEN 1 ELSE 0 END AS BIT)
        END AS IsPremiumUser
        FROM Users";
var users = conn.Query<User>(sql);

Other option will be using dynamic query with manual mapping results to user class:

var sql = @"SELECT Id, Name, CreationDate, IsPremiumUser FROM Users";
var millenium = new DateTime(2000, 1, 1);

var users = conn.Query(sql).Select(row => new User {
       Id = row.Id,
       Name = row.Name,
       IsPremiumUser = row.IsPremiumUser == null
           ? row.CreationDate < millenium
           : row.IsPremiumUser
    });

Upvotes: 1

Related Questions