web-dev-qa-db-ja.com

辞書<string、string>は、Automapperを使用してオブジェクトにマップします

以下のコードはこの質問のためのものです

私はクラスを持っています

public User class
{
 public string Name{get;set;}
 public string Age{get;set;
}

私は次のような辞書を持っています

Dictionary<string,string> data= new Dictionary<string,string>(); 
data.Add("Name","Rusi");
data.Add("Age","23");

User user= new User();

次に、Userオブジェクトをdictionaryを使用してこのAutomapperにマッピングします。オートマッパーはオブジェクトのプロパティをマップしますが、私の場合は辞書とオブジェクトがあります。

だから、どうすればこれを行うことができます私に提案してください

19
Rusi Nova

AutoMapperはオブジェクトのプロパティ間をマッピングし、そのようなシナリオでは動作しないことになっています。この場合、反射魔法が必要です。中間のシリアル化でごまかすことができます:

var data = new Dictionary<string, string>();
data.Add("Name", "Rusi");
data.Add("Age", "23");
var serializer = new JavaScriptSerializer();
var user = serializer.Deserialize<User>(serializer.Serialize(data));

そして、もしあなたがAutoMapperの使用を主張するなら、あなたは例えば次のような線に沿って何かをすることができます:

Mapper
    .CreateMap<Dictionary<string, string>, User>()
    .ConvertUsing(x =>
    {
        var serializer = new JavaScriptSerializer();
        return serializer.Deserialize<User>(serializer.Serialize(x));
    });

その後:

var data = new Dictionary<string, string>();
data.Add("Name", "Rusi");
data.Add("Age", "23");
var user = Mapper.Map<Dictionary<string, string>, User>(data);

サブオブジェクトを含むより複雑なオブジェクト階層を処理する必要がある場合は、次の質問を自問する必要があります。Is Dictionary<string, string>この場合に使用する正しいデータ構造?

24
Darin Dimitrov

AutoMapperは非常に柔軟なソリューションです。あなたはおそらくカスタムマッピングプロファイルを使用してこれを達成することができます、例えば:

public class UserMappingProfile : Profile
{
  // Props
  public override string ProfileName { get { return "UserMappingProfile"; } }

  // Methods
  public override void Configure()
  {
    CreateMap<User, Dictionary<string, string>>().ConvertUsing<DictionaryTypeConverter>();
    base.Configure();
  }

  // Types
  internal class DictionaryTypeConverter : ITypeConverter<User, Dictionary<string, string>>
  {
    public User Convert(ResolutionContext context)
    {
      var dict = context.SourceValue as Dictionary<string, string>;
      if (dict == null)
        return null;

      return new User() { Name = dict["Name"], Age = dict["Age"] };
    }
  }
}

これで、マッパーのカスタムインスタンスを作成できます。

var config = new Configuration(new TypeMapFactory(), MapperRegistry.AllMappers());
config.AddProfile<UserMappingProfile>();

config.AssertConfigurationIsValid();

var mapper = new MappingEngine(config);

私はおそらくこれを行うことができます:

var dict = new Dictionary<string, string> { { "Name", "Matt" }, { "Age", "27" } };
var user = mapper.Map<User, Dictionary<string, string>>(dict);
5
Matthew Abbott

この質問に遭遇したばかりなので、AutoMapperの現在のバージョンで可能な答えを追加したいと思います(元の質問がすでにかなり古い場合でも)。

public class MyConfig
{
    public string Foo { get; set; }
    public int Bar { get; set; }
}
var config = new MapperConfiguration(cfg => {});
var mapper = config.CreateMapper();

var source = new Dictionary<string, object>
{
    ["Foo"] = "Hello",
    ["Bar"] = 123
};
var obj = mapper.Map<MyConfig>(source);
obj.Foo == "Hello"; // true
3
mkuckert

はるかに簡単なソリューション。 KeyValuePairからオブジェクトをマッピングするだけです。例:

CreateMap<KeyValuePair<Guid, string>, User>()
            .ForMember(u => u.Id, src => src.MapFrom(x => x.Key))
            .ForMember(u => u.Name, src => src.MapFrom(x => x.Value));
1
Brandon Kelton

このスレッドは少し古いですが、公式 documentation

AutoMapperは、明示的な構成なしで動的オブジェクトとの間でマップできます(...)同様に、ディクショナリからオブジェクトに直接マップできます。AutoMapperは、キーをプロパティ名と並べます。