【问题标题】:Map a Uri field using Dapper使用 Dapper 映射 Uri 字段
【发布时间】: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 * 的解决方案)。

【问题讨论】:

    标签: dapper


    【解决方案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; },则它不起作用。
    • 我很确定我们在同一页面上 - 我用我用来测试它的确切代码更新了我的答案 - 完全符合我的预期。
    猜你喜欢
    • 2012-08-18
    • 2011-08-19
    • 2018-03-27
    • 2015-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多