使用 Dapper 映射 Uri 字段

Posted

技术标签:

【中文标题】使用 Dapper 映射 Uri 字段【英文标题】:Map a Uri field using Dapper 【发布时间】:2012-12-18 00:20:06 【问题描述】:

使用 Dapper 将字符串列映射到 Uri 属性的最简洁方法是什么?

这是迄今为止我能想到的最干净的(使用ITypeMap functionality):

查询:

SELECT * FROM TableWithAStringAddressColumn

POCO:

public class MyPoco
   
    [ColumnSetter("DapperAddress")]
    public Uri Address  get; set; 
    private string DapperAddress  set  this.Address = new Uri(value);  

扩展:

partial class SqlMapper

    public static void InitializeTypeMaps()
    
        SqlMapper.SetTypeMap(
            typeof(MyPoco),
            new CustomPropertyTypeMap(typeof(MyPoco), SqlMapper.CustomSetterMapper));

        // call out every other class that needs this kind of mapping
    

    public static Func<Type, string, PropertyInfo> CustomSetterMapper =
        (type, columnName) =>
        
            PropertyInfo prop = type
                .GetProperties()
                .FirstOrDefault(p => string.Equals(columnName, p.Name, StringComparison.OrdinalIgnoreCase));

            if (prop != null)
            
                // find out if we need to use a different setter
                ColumnSetterAttribute setterAttribute = prop.GetCustomAttributes(false).OfType<ColumnSetterAttribute>().LastOrDefault();
                if (setterAttribute != null)
                
                    PropertyInfo setterProp = type
                        .GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
                        .FirstOrDefault(p => string.Equals(setterAttribute.Setter, p.Name, StringComparison.OrdinalIgnoreCase));
                    if (setterProp == null)
                    
                        throw new InvalidOperationException(string.Format("Setter property misconfigured (Property=0, Setter=1)", prop.Name, setterAttribute.Setter));
                    
                    else
                    
                        prop = setterProp;
                    
                
            
            return prop;
        ;

自定义属性:

public class ColumnSetterAttribute : Attribute

    public string Setter  get; set; 

    public ColumnSetterAttribute(string setter)
    
        this.Setter = setter;
    

[edit] 我正在寻找一种无需在所有查询中调用所有列即可使用的解决方案(我想找到一个可以使用SELECT * 的解决方案)。

【问题讨论】:

【参考方案1】:

看起来工作量很大……

这样不行吗?

public class MyPoco

    private string _uriMapper;

    public Uri SomeUri
    
        get  return new Uri(_uriMapper); 
    

    public string Mapper  set  _uriMapper = value;  

编辑:

public class UriContainer

    private string _uriMapper;

    public string UriMapper  set  _uriMapper = value;  

    public int Id  get; set; 

    public Uri SomeUri  get return new Uri(_uriMapper); 




public class DbTests

    [Test]
    public void Can_Get_A_Uri()
    
        using (var c = new SqlConnection("hello"))
        
            c.Open();

            var uri = c.Query<UriContainer>("select *, someuri as urimapper from uris where id = 3").Single();

            Console.WriteLine(uri.SomeUri);
        
    

【讨论】:

你是对的。如果我在我的查询中调用我的所有列并将特别的列命名为别名,那将起作用。 SELECT Column1, Column2, SomeUri AS Mapper FROM TableName 但是,我正在寻找一种解决方案,我不必在所有查询中调出所有列。 好的,不能直接在列之后命名映射属性?此外,您不需要调用所有列,只需调用您想要别名的列 - 这有效:“select *, someUri as mapper from table” 正确,我想为我的属性(Uri 类型)使用与表中相同的名称。为了满足 Dapper 的要求,似乎不得不重命名一侧或另一侧。不幸的是,如果您为 Uri 属性使用与 SQL 列相同的名称,SELECT *, SomeUri AS Mapper 技巧将不起作用。 实际上,如果 Uri 属性只是一个 getter Uri SomeUri get ... SELECT *, SomeUri AS Mapper 技巧确实有效。如果您将SomeUri 设为自动属性public Uri SomeUri get; set; ,则它不起作用。 我很确定我们在同一页面上 - 我用我用来测试它的确切代码更新了我的答案 - 完全符合我的预期。

以上是关于使用 Dapper 映射 Uri 字段的主要内容,如果未能解决你的问题,请参考以下文章

Dapper数据库字段和model属性映射

如何在 Dapper 上执行严格的映射

没有自定义 SQL 的 Dapper 中的多重映射

Dapper 可以返回映射对象和其他非映射值吗?

使用 Dapper 映射嵌套对象列表

Dapper 映射结果列表