2011-07-11 8 views
6

tengo THS función para consultar un conjunto de registros de la BD:Adición de un dónde/cláusula ORDER BY en IQueryable

public IQueryable<PointTransactionViewModel> GetPointTransactions(int UserID) 
     { 
      return 
       (
        from PointTransaction p in entities.PointTransaction 
        join ActivityLog a in entities.ActivityLog 
        on p.TransactionID equals a.TransactionID 
        where p.UserID == UserID 
        select new PointTransactionViewModel 
        { 
         ID = p.TransactionID, 
         Balance = p.Balance, 
         Points = p.Amount, 
         RelatedActivityID = a.ID, 
         When = p.When, 
         Sender = p.SenderUserInfo.CompleteName 
        } 
       ); 
     } 

deseo añadir una causa adicional, como este

var entries = GetPointTransaction(1); 
return entries.OrderbyDescending.Where(x => x.When >= start && w.When <= end). 
       (x => x.When); 

Sin embargo, parece que necesito crear una nueva consulta a partir de la existente para que esto funcione. Sin embargo, parece que tengo este trabajo antes sin crear una nueva consulta, en el fragmento de código antes:

public PaginatedList(IQueryable<T> source, int pageIndex, int pageSize) 
     { 
      PageIndex = pageIndex; 
      PageSize = pageSize; 
      TotalCount = source.Count(); 
      TotalPages = (int)Math.Ceiling(TotalCount/(double)PageSize); 

      this.AddRange(source.Skip(PageIndex * PageSize).Take(PageSize)); 
     } 

¿El código de alguna manera no necesita una nueva consulta que se creará para el objeto de origen IQueryable? ¿Se creó un objeto temporal?

Editar

Es extraño, pero para conseguir que funcione tengo que hacer lo siguiente:

IQueryable<ActivityLogEntry> log = activityRepo.GetPointTransaction(userID). 
    Where(x => x.PointsEarned == 50); 
return log.ToList(); 

El siguiente no funcionará:

var log = = activityRepo.GetPointTransaction(userID); 
log.Where(x => x.PointsEarned == 50); 
return log.ToList(); 

No hay mensaje de error, solo que la cláusula where parece ignorada (también devuelve todos los datos que PointsEarned no es 50)

Respuesta

14

Su entries es una variable IQueryable, por lo que es suficiente y puede agregar cualquier cantidad de cláusulas antes de obtener datos (como antes de ToList()). No se ejecuta, solo se creará el árbol de expresiones hasta que obtenga datos.

var query = context.Where(x=>x.id == test); 
query = query.Where(anotherCondition1); 
query = query.Where(anotherCondition2); 
... 
var result = query.ToList(); 

es igual a

var result = context.Where(x=>x.id == test).Where(anotherCondition1) 
        .Where(anotherCondition2)....ToList() 

Ver LINQ and Deferred Execution

+0

me las arreglé para conseguir que funcione, pero no pude usar var para almacenar el objeto IQueryable. He actualizado el código en mi pregunta. ¡Gracias! – Extrakun

+0

@Extrakun, no puedo probar tu código actual, pero ¿cuál es el mensaje de error? en compilación o en tiempo de ejecución? o que pasa? –

+0

No hay ningún mensaje de error, solo que se ignora la cláusula where y la cláusula orderby. – Extrakun

2

sí es necesario para crear un nuevo objeto. IQueryable es inmutable. No te preocupes, así es como se supone que debes hacerlo. Así es como las consultas se forman internamente. Todos los métodos de extensión como "Dónde" no cambian realmente el objeto. Acaban de devolver uno nuevo.

El código que dice que funciona no debería funcionar. El método ni siquiera tiene un tipo.

+0

Funciona. Es un método genérico y debes especificar el tipo. – Extrakun

0

Como han señalado otros, no necesita un objeto nuevo. Sin embargo, su sintaxis para OrderByDescending es errónea, debe especificar el selector de clave.

var entries = GetPointTransaction(1); 
return entries.Where(x => x.When >= start && w.When <= end).OrderbyDescending(x => x.When); 
3

quiero decir que usted puede escribir esta muestra:

opportunites = from opp in oppDC.Opportunities 
join org in oppDC.Organizations on opp.OrganizationID equals org.OrgnizationID 
select new 
         { 
          opp.OpportunityID, 
          opp.Title, 
          opp.PostedBy, 
          opp.Address1, 
          opp.CreatedDate, 
          org.OrganizationName 
         }; 
if(condition) 
{ 
    opportunites = opportunites.Where(opp => opp.Title.StartsWith(title)); 
} 
//------Other Condition you need 
if(!String.IsNullOrEmpty(title)) 
{ 
    opportunites = opportunites.Where(.....); 
} 

if(!String.IsNullOrEmpty(name)) 
{ 
    opportunites = opportunites.Where(.....); 
}