Me encontré con este caso en el que obtengo una ParentEntity de la base de datos y quiero asignarla a ParentDto. Bastante estándar. Las clases Padres son abstractas y tienen alrededor de 10 propiedades. Hay 4 clases derivadas con 1-2 propiedades adicionales cada una.
Por lo general, solo hago este tipo de cosas con una expresión de cambio y no me preocupo por el código duplicado, pero normalmente tiene 1-2 propiedades y 1-2 casos. ¿Hay alguna solución limpia para esto?
public abstract record ParentEntity(); public record Child1Entity() : ParentEntity; public record Child2Entity() : ParentEntity; public record Child3Entity() : ParentEntity; public abstract record ParentDto(); public record Child1Dto() : ParentDto; public record Child2Dto() : ParentDto; public record Child3Dto() : ParentDto; var dbEntity = new ParentEntity(); // comes from the Database and can be child1, child2, child3 ParentDto dto = dbEntity switch { Child1Entity e => new Child1Dto(), Child2Entity e => new Child2Dto(), Child3Entity e => new Child3Dto(), };Esto es lo que suelo hacer
ParentDto dto2 = dbEntity switch { Child1Entity e => new Child1Dto(Prop1 = e.Prop1, Prop2 = e.Prop2... Child1Prop = e.Child1Prop), Child2Entity e => new Child2Dto(Prop1 = e.Prop1, Prop2 = e.Prop2... Child2Prop = e.Child2Prop), Child3Entity e => new Child3Dto(Prop1 = e.Prop1, Prop2 = e.Prop2... Child3Prop = e.Child3Prop), };Esto y mucho peor es lo que sucedería si hiciera esto con una expresión de cambio.
var dt3 = new ParentDto(); dto3.Prop1 = dbEntity.Prop1; dto3.Prop2 = dbEntity.Prop2; ... dto3.Prop10 = dbEntity.Prop10; if(dbEntity is Child1Entity child1) dto3.Child1Prop = child1.Child1Prop if (dbEntity is Child1Entity child2) dto3.Child2Prop = child2.Child2Prop if (dbEntity is Child1Entity child3) dto3.Child2Prop = child3.Child3PropEsto ni siquiera se compila porque ParentDto es abstracto. Así es como no duplicaría el código. Pero tampoco es particularmente bonito.
¿Hay alguna manera de hacer esto sucintamente? Preferiblemente sin AutoMapper.
Sin usar Automapper y demás, sugeriría crear un método para convertir uno en otro. Algo como el ejemplo anterior, limpio y legible:
public static ParentDTO ToParentDTO(ParentEntity myEntity) { return new ParentDTO() { Prop1 = myEntity.Prop1, (...) }; }Además, puede usar LINQ para un enfoque completo
var parentDTO = parents.Select(x => ToParentDTO(x)).ToList();(consulte esta respuesta ¿La forma más limpia de asignar una entidad a DTO con Linq Select? )