Reputation: 389
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
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);
Pros: Keep SQL queries free of logic. Factory is more flexible over time.
Cons: More code
Upvotes: 0
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