Mapping Properties to String Keys

本文介绍了一个名为PropertyMapper的实用类,它能够将对象属性映射为字符串键,并允许为这些键设置新值。该类特别适用于EntityFramework Code-First环境中,用于处理具有大写名称或下划线的数据库表结构。

Introduction

PropertyMapper<T> 是一个帮助类,允许映射对象属性到string keys.这也允许把新的值赋值给这些string keys.

开始写这些代码是用在EntityFramework Code-First.我也一个带有很多大写名称或下划线的数据列的表结构, 我不希望重新定义表结构 ,所以我决定写一个帮助类把对象属性映射到string keys, 从对象实例中分离值 并且快速映射回原有的original string keys,格式化成字典。

Source Code

public sealed class PropertyMapper<T>
{
    private readonly Dictionary<string, string> m_maps = new Dictionary<string, string>();
    private readonly Dictionary<string, string> m_props = new Dictionary<string, string>();

    private static string GetPropertyName<TReturn>(Expression<Func<T, TReturn>> property)
    {
        var expr = property.Body as MemberExpression;
        if (expr == null)
            throw new InvalidOperationException("Invalid property type");
        return expr.Member.Name;
    }

    public void MapProperty<TReturn>(Expression<Func<T, TReturn>> property, string mapTo)
    {
        var propName = GetPropertyName(property);
        m_maps[mapTo] = propName;
        m_props[propName] = mapTo;
    }

    public string GetPropertyMap<TReturn>(Expression<Func<T, TReturn>> property)
    {
        return GetPropertyMap(GetPropertyName(property));
    }

    public string GetPropertyMap(string property)
    {
        string result;
        return m_props.TryGetValue(property, out result) ? result : null;
    }

    public object GetPropertyValue(T instance, string property)
    {
        string result;
        if (!m_maps.TryGetValue(property, out result))
            return null;
        return typeof (T).GetProperty(result).GetValue(instance, null);
    }

    public IDictionary<string, object> GetPropertyValues(T instance)
    {
        return m_maps
            .Select(x => new {Name = x.Key, Value = typeof (T).GetProperty(x.Value).GetValue(instance, null)})
            .Where(x => x.Name != null && x.Value != null)
            .ToDictionary(x => x.Name, x => x.Value);
    }
}

Using the Code

定义类:
public sealed class Test
{
    public string Foo { get; set; }
    public string Bar { get; set; }
}

使用:
var mapper = new PropertyMapper<Test>();

mapper.MapProperty(x => x.Foo, "PROP-FOO");
mapper.MapProperty(x => x.Bar, "PROP-BAR");

var t = new Test {Foo = "Value-Foo", Bar = "Value-Bar"};

Console.WriteLine("Single property:");
var propMap = mapper.GetPropertyMap(x => x.Foo);
Console.WriteLine("{0}={1}", propMap, mapper.GetPropertyValue(t, propMap));
Console.WriteLine();

Console.WriteLine("All properties:");
foreach (var item in mapper.GetPropertyValues(t))
    Console.WriteLine("{0}={1}", item.Key, item.Value);

输出:
Single property:
PROP-FOO=Value-Foo

All properties:
PROP-FOO=Value-Foo
PROP-BAR=Value-Bar

文章出处:http://www.codeproject.com/Tips/824912/Mapping-Properties-to-String-Keys

Attempts to compute a mapping for the specified key and its current mapped value (or null if there is no current mapping). For example, to either create or append a String msg to a value mapping: map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg)) (Method merge() is often simpler to use for such purposes.) If the remapping function returns null, the mapping is removed (or remains absent if initially absent). If the remapping function itself throws an (unchecked) exception, the exception is rethrown, and the current mapping is left unchanged. The remapping function should not modify this map during computation. Params: key – key with which the specified value is to be associated remappingFunction – the remapping function to compute a value Returns: the new value associated with the specified key, or null if none Throws: NullPointerException – if the specified key is null and this map does not support null keys, or the remappingFunction is null UnsupportedOperationException – if the put operation is not supported by this map (optional) ClassCastException – if the class of the specified key or value prevents it from being stored in this map (optional) IllegalArgumentException – if some property of the specified key or value prevents it from being stored in this map (optional) Implementation Requirements: The default implementation is equivalent to performing the following steps for this map: V oldValue = map.get(key); V newValue = remappingFunction.apply(key, oldValue); if (newValue != null) { map.put(key, newValue); } else if (oldValue != null || map.containsKey(key)) { map.remove(key); } return newValue; The default implementation makes no guarantees about detecting if the remapping function modifies this map during computation and, if appropriate, reporting an error. Non-concurrent implementations should override this method and, on a best-effort basis, throw a ConcurrentModificationException if it is detected that the remapping function modifies this map during computation. Concurrent implementations should override this method and, on a best-effort basis, throw an IllegalStateException if it is detected that the remapping function modifies this map during computation and as a result computation would never complete. The default implementation makes no guarantees about synchronization or atomicity properties of this method. Any implementation providing atomicity guarantees must override this method and document its concurrency properties. In particular, all implementations of subinterface java.util.concurrent.ConcurrentMap must document whether the remapping function is applied once atomically only if the value is not present. 这个map的compute方法的注释是什么意思?
最新发布
10-17
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值