2009-11-04 7 views
7

Estoy luchando por unir los conceptos de un buen diseño de base de datos con un buen diseño orientado a objetos.Devolución de datos de la base de datos en .net: ¿Devuelve una tabla de datos o LIst <T>?

Tradicionalmente si quería ver una lista de las noticias en un repetidor, me gustaría utilizar algo como:

<script runat="server"> 

    void ShowNews() 
    { 
     rptNewsStories.DataSource = News.GetAllNews(); // Returns a DataTable 
     rptNewsStories.DataBind(); 
    } 

</script> 

<asp:Repeater id="rptNewsStories" runat="server"> 
    <ItemTemplate> 
     <div> 
      <span class="Title"><%# Eval("Title")"%> (<%# Eval("Location")"%>)</span> 
      <p> 
       <%# Eval("Summary")"%> 
      </p> 
      <ul> 
       <li>Added by: <%# Eval("AddedByFullName")%></li> 
       <li>Added on: <%# Eval("AddedOn")%></li> 
      </ul> 
     </div> 
    </ItemTemplate> 
</asp:Repeater> 

Aquí News.GetAllNews() devuelve unDataTable, que es sólo una volcado de lo que devuelve el procedimiento almacenado. El procedimiento almacenado se escribe para devolver datos mediante el uso de combinaciones, por lo que hay más de una tabla de datos valiosos.

La ventaja de esto en que, en la base de datos del procedimiento almacenado puede averiguar quien añadió la noticia de la AddedByID que existe en las noticias mesa y devolver las personas nombre completo como el valor AddedByFullName devuelto .

Sin embargo si intento y soltar el uso de un DataTable y en lugar de devolver una lista de los objetos de noticias, me sale el siguiente:

<script runat="server"> 

    void ShowNews() 
    { 
     rptNewsStories.DataSource = News.GetAllNews(); // Returns a List<News> 
     rptNewsStories.DataBind(); 
    } 

</script> 

<asp:Repeater id="rptNewsStories" runat="server"> 
    <ItemTemplate> 
     <div> 
      <span class="Title"><%# Eval("Title")"%> (<%# Eval("Location")"%>)</span> 
      <p> 
       <%# Eval("Summary")"%> 
      </p> 
      <ul> 
       <li>Added by: <!-- Here there is only a AddedByUserID, not an AddedByFullName value --></li> 
       <li>Added on: <%# Eval("AddedOn")%></li> 
      </ul> 
     </div> 
    </ItemTemplate> 
</asp:Repeater> 

Pero ahora me quedo con el problema de que ciertos valores que Quiero mostrar (Como AddedByFullName) no existen dentro del objeto Noticias, porque no son algo que está explícitamente establecido, sino que se recuperan de un ID de búsqueda en el objeto.

Me gustaría devolver objetos en lugar de DataTables, pero no sé la mejor manera de cerrar esta brecha.

Do I:
* Crear propiedades adicionales en las Noticias
clase para cada valor adicional que se puede devolver a la base de datos en relación con estos datos?
* ¿Quédate con DataTables para casos específicos donde hay muchos valores adicionales?

¿O simplemente estoy en el camino equivocado?

Respuesta

4

Sus opciones están restringidas por la tecnología subyacente que está dispuesto para su uso como acceso a datos. Por el momento hay varias alternativas que el conjunto de herramientas de VS y .NET Framework son compatibles:

A partir de estos, todos los conjuntos de datos, excepto ADO.Net, le permiten especificar las relaciones de navegación como usted lo hace, ya sea con ansiedad o con poca carga. En un caso como el que describes, la clave natural para estas tecnologías sería modelar explícitamente la relación entre el artículo de Noticias y el autor en los diseñadores y dejar que el marco aborde el problema de cargar los datos apropiados y los tipos apropiados, lo que en última instancia significa que el problema de unión se maneja implícitamente por la capa de acceso a los datos de la aplicación (el marco) y no por un procedimiento almacenado creado explícitamente.

La elección de la tecnología fluctuará en todas partes en su código, desde cómo obtiene sus datos hasta cómo lo visualiza y cómo actualiza, ninguna de estas tecnologías es fácilmente intercambiable. Personalmente, encuentro que el equilibrio correcto de potencia y complejidad es con LINQ to SQL.

+0

Gracias por su entrada Remus - Escuché que MS estaba deteniendo el desarrollo de LINQ to SQL a favor de Entity Framework. ¿Es esto cierto y, en caso afirmativo, alentarías los nuevos desarrollos con esta tecnología? –

+0

@Peter: ya no estoy con EM así que realmente no sabría más de lo que es conocimiento público. Es cierto que EF es la forma recomendada en el futuro, pero dada la abrumadora adopción de LINQ to SQL en comparación con EF, me sorprendería verlo completamente abandonado. –

+0

Actualmente estoy usando y disfrutando LINQ2SQL para un proyecto .net 3.5. Mi próximo gran proyecto usará .net 4.0, así que usaré Entity Framework 4.0 –

0

Buena pregunta:

Hay un par de enfoques que puede tomar:

  1. Puede recuperar los datos adicionales que necesita en el proceso de unión del repetidor y rellenarla en un " marcador de posición "para cada registro de noticias devuelto. Esto tiene problemas de rendimiento debido a las consultas adicionales, pero funcionará.

  2. De ser posible, modificaría el objeto de noticias para que contenga la información adicional, o crearé un objeto que herede del objeto de noticias que tenía la información adicional o las propiedades contenidas en él.

Esperanza esto ayuda :-) 1

Editar/Comentario: creo que la fricción que está viendo en su diseño es que no se está reconociendo el "-tiene una" relación entre su objeto de noticias y lo que yo llamaría su autor/colaborador.La unión que estás haciendo en tu consulta simplemente oculta la falta de relación en el modelo de objetos.

+0

Gracias por la entrada de Aquiles: 1) Similar a la sugerencia de Gregoire. Como dices, hará el trabajo, pero este tipo de enfoque simplemente parece un trabajo extra. 2) Sé que esto será más eficiente, pero aún se siente un poco agudo ... aunque lo prefiero por la opción 1 Propósito Espero una sugerencia que se sienta bien, donde estos enfoques no lo hacen se siente como un ajuste perfecto. –

+0

Creo que la fricción que está viendo en su diseño es que no está reconociendo la relación "tiene-a" entre su objeto de noticias y lo que yo llamaría su autor/colaborador. La unión que estás haciendo en tu consulta simplemente oculta la falta de relación en el modelo de objetos. – Achilles

+0

Buen punto, bien hecho –

0

usted puede probar esto, tal vez no sea la mejor solución:

void ShowNews() 
{ 
    User[] usersConcerned = News.GetAllUsersLinkedWithNews(); //only return the users concerned by the news 
    List<News> news = News.GetAllNews(); 
    foreach(News item in news) 
    { 
     item.AddedByUser = usersConcerned.FirstOrDefault(u=>u.Id == item.AddedByUserID); 
    } 
    rptNewsStories.DataSource = news ; 
    rptNewsStories.DataBind(); 
} 
+0

Este tipo de enfoque me pasó por la mente, pero parece estar haciendo algo que sería mejor manejado por una combinación en un procedimiento almacenado. Pero entonces tal vez esto es más OO? :) –

+0

@Peter, debe hacer el filtrado de datos en el nivel de la base de datos. Podría pasar New.GetAllNews (usersConcerned) y manejar la matriz en su proceso. Esto podría reducir drásticamente la cantidad de tráfico de red según sus datos. –

Cuestiones relacionadas