Dapper: asignación de conjuntos de resultados múltiples que usan herencia de tablas

dapper inheritance

Pregunta

Tengo la siguiente estructura de clase y la estructura de base de datos coincidente que intento mapear. Tengo una clase de diseño que contiene una lista de elementos. Puede haber 3 tipos diferentes de elementos: texto, forma e imagen. Utilizo una clase abstracta para mantener las propiedades comunes entre las formas y la estructura de mi base de datos refleja eso.

Mi procedimiento almacenado devuelve dos juegos de registros, uno con los diseños y otro con todos los elementos. El conjunto de registros del elemento utiliza combinaciones a la izquierda para devolver todos los elementos junto con sus propiedades no comunes. Cada elemento tiene un ElementTyepID que determina qué tipo de elemento es. Mi clase de diseño contiene una lista. ¿Hay alguna manera de tomar ese segundo conjunto de resultados y hacer que se asocie a la subclase correcta de Element basada en ElementTypeID?

public class Design
{
   public int DesignID {get;set;}
   public string DesignName {get;set;}
   public List<Element> ElementList {get;set;}
}

public class Element
{
   public int ElementID {get;set;}
   public int DesignID {get;set;}
   public int ElementTypeID {get;set;}
   public int Width {get;set;}
   public int Height {get;set;}
   public string Color {get;set;}
}

public class ElementText
{
   public int ElementTextID {get;set;}
   public int ElementID {get;set;}
   public string Font {get;set;}
   public string TextValue {get;set;}
}

public class ElementShape
{
   public int ElementShapeID {get;set;}
   public int ElementID {get;set;}
   public int ShapeType {get;set;}
}

public class ElementImage
{
  public int ElementImageID int {get;set;}
  public int ElementID {get;set;}
  public string ImageURL {get;set;}
}




Table: Design
-------------
DesignID int
DesignName varchar(50)


Table: Element
--------------
ElementID int
DesignID int
ElementTypeID int 0-Text, 1-Shape, 2-Image
Width int
Height int
Color varchar(10)


Table: ElementText
------------------
ElementTextID int
ElementID int
Font varchar(50)
TextValue varchar(50)



Table: ElementShape
-------------------
ElementShapeID int
ElementID int
ShapeType int



Table: ElementImage
-------------------
ElementImageID int
ElementID int
ImageURL varchar(255)



Create Table #Designs
(
  [DesignID] [int] NOT NULL,
  [DesignName] [varchar](50) NOT NULL,
)

-- Place all designs into a temp table
Insert Into #Designs
Select DesignID, DesignName from Design

-- Return 1st Result Set (Designs)
select * from #Designs

-- Return 2nd Result Set (Elements)
select * from Element as e
left Join ElementText as t on e.ElementID=t.ElementID
left Join ElementShape as s on e.ElementID=s.ElementID
left Join ElementImage as c on e.ElementID=c.ElementID
Where e.DesignID in (Select DesignID from #Designs)
Order By e.ElementID ASC

Respuesta experta

Este enfoque sindical no es uno que dapper apoya directamente. Puede tener algo de suerte con la API de Query<…> que acepta múltiples argumentos de tipo genérico, uno por división horizontal, y utiliza el selector final para crear el objeto correcto. Alternativamente, es posible que pueda utilizar la API no genérica y sacar las columnas de forma manual (aunque puede tener problemas si hay nombres de columna duplicados).

Pero para algo automático, la característica debería ser considerada, diseñada, especificada, implementada, probada y respaldada. Estas cosas no han sucedido todavía para este escenario.


Respuesta popular

No veo por qué la api multimap fuera de la caja no funcionaría. Debido a que los tipos de elemento no heredan de una clase común, simplemente debe devolverlos en una tupla ... Posteriormente, puede evaluar si son nulos o no y decidir qué hacer con ellos.

Query<Element,ElementText,ElementShape,ElementDesign,Tuple<Element,ElementText,ElementShape,ElementDesign>>(<sql>,
(e,et,es,ed)=>{return Tuple.Create(e,et,es,ed)}, spliton:"ElementID,ElementTextID,ElementShapeID,ElementDesignID");

He estado en una situación similar en la que tenemos 'MessageRecipients' que pueden ser objetos User, Account, Location y están diferenciados por 'MessageRecipientType'.



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow