.NET Dapper - 映射计算属性
Posted
技术标签:
【中文标题】.NET Dapper - 映射计算属性【英文标题】:.NET Dapper - Mapping computed properties 【发布时间】:2017-03-15 11:27:40 【问题描述】:我正在使用 Dapper 处理 .NET 项目中的数据库连接。自动列映射效果很好,我还可以将列映射到模型中的不同属性名称。但是,如何映射计算属性?例如,我的模型是
class User
public int Id get; set;
public string Name get; set;
public bool IsPremiumUser get; set;
桌子是
Id | Name | CreationDate | IsPremiumUser
现在,IsPremiumUser 在 db 中可以为 null,但在模型中则不能。我希望它被以下逻辑映射:
if (row.IsPremiumUser != null)
model.IsPremiumUser = row.IsPremiumUser;
else
model.IsPremiumUser = row.CreationDate < 1.1.2000;
换句话说,它的值取决于 2 列。还有多种情况我想根据是否存在某种关系来设置布尔属性。如何处理这些更复杂的映射情况?
【问题讨论】:
当您尝试将项目保存回数据库时,此映射应如何工作?如果IsPremiumUser
为空(当你读到它时),它应该被更新并有一个值吗?
也许你只需要额外的属性来计算但不会映射到数据库表?
是的,这正是我的意思。这些计算值不会保存回 db。
【参考方案1】:
只需使用 SQL 查询,它将检查 IsPremiumUser
字段是否不为空,如果用户没有设置此标志,则返回创建日期检查结果:
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);
其他选项将使用动态查询并手动将结果映射到用户类:
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
);
【讨论】:
谢谢,我最终使用了这种方法,尽管这并不是我的想法。如果我有一些更复杂的映射逻辑不方便在 db 端做呢? @eko 请刷新页面 :) 请记住,Dapper 会将 IsPremiumUser 标志返回为 null 或布尔值。它不会返回可为空的布尔值【参考方案2】:另一种选择是建立一个工厂,让它组装用户:
var userRecords = _connection.Query<UserRecord>("select * from users");
var users = UserFactory.Build(userRecords);
UserRecord 类仅用于查询数据
工厂将处理属性映射和动态属性
优点:保持 SQL 查询没有逻辑。随着时间的推移,工厂变得更加灵活。
缺点:更多代码
【讨论】:
以上是关于.NET Dapper - 映射计算属性的主要内容,如果未能解决你的问题,请参考以下文章