2008-09-06 15 views
6

Parte de la aplicación web en la que estoy trabajando es un área que muestra los mensajes de la administración a 1 ... n usuarios. Tengo un proyecto de DataAccess que contiene las clases de LINQ a SQL y un proyecto de sitio web que es la IU. Mi base de datos es el siguiente:Mejores prácticas re: LINQ a SQL para acceso a datos

de usuario -> MessageDetail < - Mensaje < - MessageCategory

MessageDetail es una tabla de unión que también contiene una bandera IsRead.

La lista de mensajes está agrupada por categoría. Tengo dos controles ListView anidados en la página: uno emite el nombre del grupo, mientras que el otro anidado dentro está vinculado a MessageDetails y emite los mensajes ellos mismos. En el código subyacente de la página de lista de los mensajes que tengo el siguiente código:

protected void MessageListDataSource_Selecting(object sender, LinqDataSourceSelectEventArgs e) 
{ 
    var db = new DataContext(); 

    // parse the input strings from the web form 
    int categoryIDFilter; 
    DateTime dateFilter; 
    string catFilterString = MessagesCategoryFilter.SelectedValue; 
    string dateFilterString = MessagesDateFilter.SelectedValue; 
    // TryParse will return default values if parsing is unsuccessful (i.e. if "all" is selected"): 
    // DateTime.MinValue for dates, 0 for int 
    DateTime.TryParse(dateFilterString, out dateFilter); 
    Int32.TryParse(catFilterString, out categoryIDFilter); 
    bool showRead = MessagesReadFilter.Checked; 

    var messages = 
     from detail in db.MessageDetails 
     where detail.UserID == (int)Session["UserID"] 
     where detail.Message.IsPublished 
     where detail.Message.MessageCategoryID == categoryIDFilter || (categoryIDFilter == 0) 
     where dateFilter == detail.Message.PublishDate.Value.Date || (dateFilter == DateTime.MinValue) 
     // is unread, showRead filter is on, or message was marked read today 
     where detail.IsRead == false || showRead || detail.ReadDate.Value.Date == DateTime.Today 
     orderby detail.Message.PublishDate descending 
     group detail by detail.Message.MessageCategory into categories 
     orderby categories.Key.Name 
     select new 
     { 
      MessageCategory = categories.Key, 
      MessageDetails = categories.Select(d => d) 
     }; 

    e.Result = messages; 
} 

Este código funciona, pero si se sigue una declaración enorme LINQ como este en el código subyacente para un control LinqDataSource simplemente doesn' siéntate bien conmigo.

Parece que todavía estoy codificando consultas en la interfaz de usuario, solo que ahora es LINQ en lugar de SQL. Sin embargo, creo que construir otra capa entre las clases L2S y la UI reduciría parte de la flexibilidad de LINQ. ¿No es el objetivo de reducir la cantidad de código que escribes para obtener datos?

¿Hay algún punto medio posible que no estoy viendo, o simplemente estoy malinterpretando la forma en que se supone que se utiliza LINQ to SQL? El consejo sería muy apreciado.

Respuesta

5

Todas sus consultas de LINQ deben estar en una clase de lógica de negocio , sin cambios desde metodologías anteriores como ADO.

Si es purist, siempre debe devolver Lista (de T) de sus métodos en la clase ejecutiva, de hecho, el contexto de datos solo debe ser visible para las clases de negocio. Luego puede manipular la lista en la interfaz de usuario.

Si es pragmatist, puede devolver un objeto IQueryable y realizar algunas manipulaciones en la interfaz de usuario.

+0

Este es prácticamente el enfoque que terminé usando. Consejos útiles, gracias –

+4

Si eres un purista, regresas IList;) O incluso mejor IEnumerable –

1

Independientemente de LINQ, creo que mezclar el código de presentación con el código de base de datos no es una buena idea. Crearía una capa simple de abstracción de base de datos además de consultas LINQ. En mi opinión LINQ es solo una herramienta conveniente, que no tiene un impacto serio en el diseño de aplicaciones tradicionales.

Cuestiones relacionadas