AutoMapper maneja fácilmente asignación uno lista de tipos de objetos a otra lista de los diferentes tipos de objetos, pero ¿es posible tenerlo mapa a una lista existente utilizando una identificación como una clave?a la lista existente en AutoMapper utilizando una clave
5
A
Respuesta
7
no he encontrado mejor manera que la siguiente.
Éstos son origen y destino.
public class Source
{
public int Id { get; set; }
public string Foo { get; set; }
}
public class Destination
{
public int Id { get; set; }
public string Foo { get; set; }
}
Definir convertidor (Debe cambiar Lista <> a cualquier tipo que esté utilizando).
public class CollectionConverter: ITypeConverter<List<Source>, List<Destination>>
{
public List<Destination> Convert(ResolutionContext context)
{
var destinationCollection = (List<Destination>)context.DestinationValue;
if(destinationCollection == null)
destinationCollection = new List<Destination>();
var sourceCollection = (List<Source>)context.SourceValue;
foreach(var source in sourceCollection)
{
Destination matchedDestination = null;
foreach(var destination in destinationCollection)
{
if(destination.Id == source.Id)
{
Mapper.Map(source, destination);
matchedDestination = destination;
break;
}
}
if(matchedDestination == null)
destinationCollection.Add(Mapper.Map<Destination>(source));
}
return destinationCollection;
}
}
Y aquí está la configuración de asignación real y el ejemplo.
Mapper.CreateMap<Source,Destination>();
Mapper.CreateMap<List<Source>,List<Destination>>().ConvertUsing(new CollectionConverter());
var sourceCollection = new List<Source>
{
new Source{ Id = 1, Foo = "Match"},
new Source{ Id = 2, Foo = "DoesNotMatchWithDestination"}
};
var destinationCollection = new List<Destination>
{
new Destination{ Id = 1, Foo = "Match"},
new Destination{ Id = 3, Foo = "DoeNotMatchWithSource"}
};
var mergedCollection = Mapper.Map(sourceCollection, destinationCollection);
Debe obtener el siguiente resultado.
1
He encontrado este artículo muy útil y, como tal, pensé que iba a alimentar de nuevo en mi versión genérica del convertidor de tipos que se puede utilizar para seleccionar la propiedad para que coincida con el de cada objeto.
Utilizando todo lo que necesita hacer es:
// Example of usage
Mapper.CreateMap<UserModel, User>();
var converter = CollectionConverterWithIdentityMatching<UserModel, User>.Instance(model => model.Id, user => user.Id);
Mapper.CreateMap<List<UserModel>, List<User>>().ConvertUsing(converter);
//The actual converter
public class CollectionConverterWithIdentityMatching<TSource, TDestination> :
ITypeConverter<List<TSource>, List<TDestination>> where TDestination : class
{
private readonly Func<TSource, object> sourcePrimaryKeyExpression;
private readonly Func<TDestination, object> destinationPrimaryKeyExpression;
private CollectionConverterWithIdentityMatching(Expression<Func<TSource, object>> sourcePrimaryKey, Expression<Func<TDestination, object>> destinationPrimaryKey)
{
this.sourcePrimaryKeyExpression = sourcePrimaryKey.Compile();
this.destinationPrimaryKeyExpression = destinationPrimaryKey.Compile();
}
public static CollectionConverterWithIdentityMatching<TSource, TDestination>
Instance(Expression<Func<TSource, object>> sourcePrimaryKey, Expression<Func<TDestination, object>> destinationPrimaryKey)
{
return new CollectionConverterWithIdentityMatching<TSource, TDestination>(
sourcePrimaryKey, destinationPrimaryKey);
}
public List<TDestination> Convert(ResolutionContext context)
{
var destinationCollection = (List<TDestination>)context.DestinationValue ?? new List<TDestination>();
var sourceCollection = (List<TSource>)context.SourceValue;
foreach (var source in sourceCollection)
{
TDestination matchedDestination = default(TDestination);
foreach (var destination in destinationCollection)
{
var sourcePrimaryKey = GetPrimaryKey(source, this.sourcePrimaryKeyExpression);
var destinationPrimaryKey = GetPrimaryKey(destination, this.destinationPrimaryKeyExpression);
if (string.Equals(sourcePrimaryKey, destinationPrimaryKey, StringComparison.OrdinalIgnoreCase))
{
Mapper.Map(source, destination);
matchedDestination = destination;
break;
}
}
if (matchedDestination == null)
{
destinationCollection.Add(Mapper.Map<TDestination>(source));
}
}
return destinationCollection;
}
private string GetPrimaryKey<TObject>(object entity, Func<TObject, object> expression)
{
var tempId = expression.Invoke((TObject)entity);
var id = System.Convert.ToString(tempId);
return id;
}
}
Cuestiones relacionadas
- 1. lista de copias AutoMapper a la lista
- 2. ¿Puede el Automapper asignar una clave externa a un objeto utilizando un repositorio?
- 3. ¿Puede Automapper mapear una lista paginada?
- 4. dependencias Inyectar AutoMapper utilizando Ninject
- 5. AutoMapper utilizando el constructor incorrecto
- 6. ¿Cómo agrego una clave externa a una tabla SQLite existente?
- 7. colecciones de asignaciones utilizando AutoMapper
- 8. Crear CSR usando la clave privada existente
- 9. Agregar un valor en un objeto hash (en Ruby), utilizando una clave ya existente?
- 10. ¿Cómo puedo crear una nueva lista de la lista existente?
- 11. SQL Agregar clave externa a la columna existente
- 12. ¿Cómo eliminar utilizando solo la clave principal?
- 13. cómo agregar una nueva columna a la clave primaria compuesta existente
- 14. ¿Estoy utilizando la funcionalidad Incluir de Automapper 2.0 correctamente?
- 15. Agregar una identidad a una columna existente
- 16. Looping a través de una lista de una clave específica al final de la lista
- 17. AutoMapper relación de muchos a muchos en la colección
- 18. PHP: is_array en $ matriz [ 'clave'] con 'clave' no existente
- 19. filtrar una lista utilizando LINQ
- 20. ¿Cómo agregar una clave primaria de incremento automático a una tabla existente, en PostgreSQL?
- 21. dividir una lista utilizando LINQ
- 22. Asignación de la lista al objeto con AutoMapper
- 23. ¿Cómo asignar una cadena a una fecha en Automapper?
- 24. SQL: establecer la columna existente como clave principal en MySQL
- 25. AutoMapper con lista de elementos secundarios anidados
- 26. ¿Cómo encontrar el valor máximo para cada clave en una lista de diccionarios utilizando LINQ?
- 27. ¿Cómo acceder a un objeto utilizando la clave dinámica?
- 28. Agregar una columna entera a una tabla mysql existente basada en la columna existente
- 29. Java Hashtable sobrescribe la clave existente con la nueva clave durante 'put'
- 30. ¿Cómo enviar evento clave a la aplicación utilizando XCB?