객체 속성과 사전 키 이름이 다른 경우 객체 / 클래스 속성을 사전에 매핑하는 방법은 무엇입니까?

시바

내가 (주식 시장 데이터에 대한) 블룸버그 서버 API를 호출하고 다시 데이터를 받고 있습니다 Dictionary<string, object>를 Where Key사전에이 인 Field Name블룸버그의 측면에서, 그리고 개체가 블룸버그에서 데이터 값을 포함 할 수있다 string, decimal, DateTime, boolean

Bloomberg 데이터를 가져온 후 반환 된 값으로 강력한 유형 엔터티 / 클래스를 채워야합니다. 블룸버그에 요청시 어떤 필드 이름을 보내 느냐에 따라 반환 된 사전은 다른 키 값을 가질 수 있습니다. 내가 가진 문제 는 블룸버그 필드 이름과 내 .net 엔티티의 속성 이름이 일치하지 않아서AutoMapper 또는 유사한 라이브러리를 사용하여이 매핑을 수행 할 수 있는지 확실하지 않습니다 .

또한 Tuple<string,string,object>첫 번째 튜플 항목이 블룸버그 필드 이름이고, 두 번째 튜플 항목이 내 엔티티의 속성 이름이고, 세 번째 튜플 항목이 블룸버그에서 반환 된 데이터 값인 곳을 사용해 보았습니다. 그것은 (지금까지) 작동하지 않으므로이 bloombergfield <-> EntityProperty 매핑을 유지 관리하고 각 필드에 대한 Bloomberg 데이터 값을 사용하여 엔티티 값을 채우는 간단한 간단한 방법이 있는지 궁금합니다. Generic (즉, C # Generics 사용) 솔루션이 훨씬 더 좋습니다!

아래에 샘플 콘솔 앱 코드를 붙여 넣었으므로 붙여 넣어 사용해 볼 수 있습니다. 2 개의 사전, 1 개의 사전 stockdata및 다른 사전 bonddata에는 가짜 데이터가 있지만 아이디어를 얻을 수 있습니다. 나는 또한 내가 달성하려는 것을 다시 반복하기 위해 아래에 주석을 추가했습니다.

감사!!

namespace MapBBFieldsToEntityProperties
{
    using System;
    using System.Collections.Generic;

    class Program
    {
        public class StockDataResult
        {
            public string Name { get; set; }
            public decimal LastPrice { get; set; }
            public DateTime SettlementDate { get; set; }
            public decimal EPS { get; set; }

        }

        public class BondDataResult
        {
            public string Name { get; set; }
            public string Issuer { get; set; }
            public decimal Duration { get; set; }
            public DateTime YieldToMaturity { get; set; }
        }


        static void Main(string[] args)
        {

            // Data Coming from Bloomberg. 
            // Dictionary Key is the Bloomberg Data Field Name. 
            // Dictionary Object is the Value returns and can be any .Net primitive Type

            // Sample Data returned for a Stock Query to Bloomberg
            Dictionary<string, object> dctBloombergStockData 
                = new Dictionary<string, object>
                            {
                                { "NAME", "IBM" },
                                {  "PX_LAST", 181.30f },
                                { "SETTLE_DT", "11/25/2013" } // This is Datetime value
                            };

            // Sample Data returned for a Bond Query to Bloomberg
            Dictionary<string, object> dctBloombergBondData = 
                new Dictionary<string, object>
                            {
                                { "NAME", "IBM" },
                                { "ISSUE_ORG","IBM Corp" },
                                {  "DURATION", 4.430f },
                                { "YLD_TO_M", 6.456f }
                            };

            // This is my Stock Entity
            StockDataResult stockData = new StockDataResult();

            // This is my Bond Entity
            BondDataResult bondData = new BondDataResult();

            // PROBLEM STATEMENT:
            //
            // Need to somehow Map the Data returned from Bloomberg into the 
            // Corresponding Strong-typed Entity for that Data Type.
            // i.e. 
            // map dctBloombergStockData to stockData Entity instance as follows
            // 
            // dctBloombergStockData."NAME" Key  <--------> stockData.Name Property so that
            // dctBloombergStockData["NAME"] value of "IBM" can be assigned to stockData.Name
            // 
            // dctBloombergStockData."PX_LAST" Key  <--------> stockData.LastPrice Property so that
            // dctBloombergStockData["PX_LAST"] value 181.30f can be assigned to stockData.LastPrice value.
            // ....
            // .. you get the idea.
            // Similarly,
            // map dctBloombergBondData Data to bondData Entity instance as follows
            // 
            // dctBloombergBondData."NAME" Key  <--------> bondData.Name Property so that
            // dctBloombergBondData["NAME"] value of "IBM" can be assigned to bondData.Name property's value
            // 
            // dctBloombergBondData."ISSUE_ORG" Key  <--------> bondData.Issuer Property so that
            // dctBloombergBondData["ISSUE_ORG"] value 181.30f can be assigned to bondData.Issuer property's value.
            //
            // dctBloombergBondData."YLD_TO_M" Key  <--------> bondData.YieldToMaturity Property so that
            // dctBloombergBondData["YLD_TO_M"] value 181.30f can be assigned to bondData.YieldToMaturity property's value.                                
        }
    }
}
알렉스

몇 가지 개선이 가능하다고 확신하지만 이것은 매핑을 지정하고 해당 맵을 사용하는 한 가지 방법입니다.

class Program
{
    public class Mapper<TEntity> where TEntity : class
    {
        private readonly Dictionary<string, Action<TEntity, object>> _propertyMappers = new Dictionary<string, Action<TEntity, object>>();
        private Func<TEntity> _entityFactory;

        public Mapper<TEntity> ConstructUsing(Func<TEntity> entityFactory)
        {
            _entityFactory = entityFactory;
            return this;
        }

        public Mapper<TEntity> Map<TProperty>(Expression<Func<TEntity, TProperty>> memberExpression, string bloombergFieldName, Expression<Func<object, TProperty>> converter)
        {
            var converterInput = Expression.Parameter(typeof(object), "converterInput");
            var invokeConverter = Expression.Invoke(converter, converterInput);
            var assign = Expression.Assign(memberExpression.Body, invokeConverter);
            var mapAction = Expression.Lambda<Action<TEntity, object>>(
                assign, memberExpression.Parameters[0], converterInput).Compile();
            _propertyMappers[bloombergFieldName] = mapAction;
            return this;
        }

        public TEntity MapFrom(Dictionary<string, object> bloombergDict)
        {
            var instance = _entityFactory();
            foreach (var entry in bloombergDict)
            {
                _propertyMappers[entry.Key](instance, entry.Value);
            }
            return instance;
        }
    }

    public class StockDataResult
    {
        public string Name { get; set; }
        public decimal LastPrice { get; set; }
        public DateTime SettlementDate { get; set; }
        public decimal EPS { get; set; }
    }

    public static void Main(params string[] args)
    {
        var mapper = new Mapper<StockDataResult>()
            .ConstructUsing(() => new StockDataResult())
            .Map(x => x.Name, "NAME", p => (string)p)
            .Map(x => x.LastPrice, "PX_LAST", p => Convert.ToDecimal((float)p))
            .Map(x => x.SettlementDate, "SETTLE_DT", p => DateTime.ParseExact((string)p, "MM/dd/yyyy", null));


        var dctBloombergStockData = new Dictionary<string, object>
        {
            { "NAME", "IBM" },
            {  "PX_LAST", 181.30f },
            { "SETTLE_DT", "11/25/2013" } // This is Datetime value
        };
        var myStockResult = mapper.MapFrom(dctBloombergStockData);

        Console.WriteLine(myStockResult.Name);
        Console.WriteLine(myStockResult.LastPrice);
        Console.WriteLine(myStockResult.SettlementDate);
    }
}

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관