自定义映射

如果查询列名称与你的类不匹配,则可以设置类型的映射。此示例演示了使用 System.Data.Linq.Mapping.ColumnAttributeas 作为自定义映射的映射。

映射只需要为每个类型设置一次,因此在应用程序启动时或在其他地方设置它们仅初始化一次。

假设再次使用与一对多示例相同的查询,并将类重构为更好的名称,如下所示:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Born { get; set; }
    public Country Residience { get; set; }
    public ICollection<Book> Books { get; set; }
}

public class Country
{
    [System.Data.Linq.Mapping.Column(Name = "CountryId")]
    public int Id { get; set; }

    [System.Data.Linq.Mapping.Column(Name = "CountryName")]
    public string Name { get; set; }
}

public class Book
{
    public int Id { get; set; }

    public string Name { get; set; }
}

注意 Book 如何不依赖 ColumnAttribute,但我们需要保持 if 语句

现在将此映射代码放在应用程序中的某个位置,只执行一次:

Dapper.SqlMapper.SetTypeMap(
    typeof(Country),
    new CustomPropertyTypeMap(
        typeof(Country),
        (type, columnName) =>
            type.GetProperties().FirstOrDefault(prop =>
                prop.GetCustomAttributes(false)
                    .OfType<System.Data.Linq.Mapping.ColumnAttribute>()
                    .Any(attr => attr.Name == columnName)))
);

var bookMap = new CustomPropertyTypeMap(
    typeof(Book),
    (type, columnName) =>
    {
        if(columnName == "BookId")
        {
            return type.GetProperty("Id");
        }

        if (columnName == "BookName")
        {
            return type.GetProperty("Name");
        }

        throw new InvalidOperationException($"No matching mapping for {columnName}");
    }        
);
Dapper.SqlMapper.SetTypeMap(typeof(Book), bookMap);

然后使用任何先前的 Query<> 示例执行查询。

此答案中显示了添加映射的更简单方法。