2011-11-30 11 views
5

Tengo una base de datos con estas dos tablas: Customer y CustomerStatus. CustomerStatus es una tabla llamada de solo lectura. Todos los cambios en el estado de un cliente dan como resultado un INSERTAR en esa tabla. El estado del cliente actual es localizable a través del CustomerStatus.StatusTimestamp.Cómo incluir una fila específica de otra tabla con LINQ a Entidades

Ahora estoy buscando una consulta LINQ para entidades que cargue a todos los clientes junto con su estado actual. Algo así como

.Include("CustomerStatus.OrderByDescending(StatusTimestamp).FirstOrDefault()").

No he encontrado una manera adecuada con EF 4.0.

Mi solución actual es muy feo y utiliza 2 pasos:

Paso 1: consulta LINQ que carga todo el estado (en la capa de negocio/datos):

var r = from c in db.Customers.Include("CustomerStatus") select c;

paso 2: tomar el estado adecuado de cada cliente en la interfaz gráfica de usuario (en un bucle en una vista MVC3):

c.CustomerStatus.OrderByDescending(i => i.StatusTimestamp).FirstOrDefault()

¿Alguna idea de cómo se puede hacer esto directamente en un solo paso?

Respuesta

2

EF es más poderoso que usted le da el crédito correspondiente. Una de las cosas que puede hacer es proyectar a los tipos complejos dentro de un IQueryable (es decir, en un hit de base de datos). Esto debería funcionar:

var data = 
    from c in db.Customers 
    select new { 
     Customer = c, 
     LastStatus = c.CustomerStatus // assuming navigation property set up right 
         .OrderByDescending(s => s.StatusTimestamp) 
         .FirstOrDefault() 
    }; 

Ahora data es un IQueryable<anonymous_type>, y cada artículo tiene una propiedad Customer dando al cliente, y una LastStatus dando el estado de última sellos de tiempo, o null si no hay ningún registro de estado para el cliente.

Puedes usar un tipo con nombre aquí también, es más rápido escribirlo de esta manera :).

+0

Funciona bien. ¡Gracias! En realidad todavía lo hago en 3 pasos, pero todo en el BLL ahora: 1: 'var q = ...'. 2: 'var l = q.ToList()' (para forzar la carga lenta del estado). 3: 'return l.Seleccione (i => i.Customer)' (para devolver un IEnumerable , y no un tipo anónimo). – mkva

-1

Algo como esto ??

var r = (from c in db.Customers.Include("CustomerStatus") 
      where c.CustomerStatus.OrderByDescending(i => i.StatusTimestamp) 
      select c).FirstOrDefault() 
+0

¿Puedes comentar por qué esto no es útil? –

+0

¡Porque no compila! – AakashM

+1

Pero eso es solo un compañero de pseudocódigo. ¿Cómo podría saber qué tienen los clientes y la clase CustomerStatus? –

0

No estoy seguro de cómo el esquema se parece pero ¿qué pasa

var query = from c in db.Customers 
      join CustomerStatus s on c.StatusTimestamp = s.StatusTimestamp 
      order by s.StatusTimestamp 
      select c; 
Cuestiones relacionadas