Linq и C #, пропуск записей, ошибка приведения

#c# #asp.net #linq #casting

#c# #asp.net #linq #Кастинг

Вопрос:

Я пытаюсь пропустить и извлечь из запроса, но получаю ошибки приведения:

 Error   1   Cannot implicitly convert type 'System.Linq.IQueryable<tblComment>' to 'System.Linq.IOrderedQueryable<tblComment>'. An explicit conversion exists (are you missing a cast?)
Error   2   Cannot implicitly convert type 'System.Linq.IQueryable<tblComment>' to 'System.Linq.IOrderedQueryable<tblComment>'. An explicit conversion exists (are you missing a cast?)
  

В строках:

 if(ToSkip > 0)
    q = q.Skip(ToSkip);
if(ToTake > 0)
    q = q.Take(ToTake);
  

Вот полный метод, любая помощь приветствуется! Все, что я пытаюсь сделать, это отфильтровать возвращаемые записи, если они указаны для этого.

Кроме того, это хороший способ сделать это, или база данных будет возвращать ВСЕ записи каждый раз? Т.е. будет ли он извлекать все записи, затем пропускать и принимать? Я хочу сделать это эффективным.

 /// <summary>
/// Fetches all comments from a category
/// </summary>
/// <param name="Category">Category ID of comments to fetch</param>
/// <param name="Identifier">Identifier ID for category</param>
/// <param name="ToTake">How many to take in query. 0 = all</param>
/// <param name="ToSkip">How many to skip.</param>
/// <returns></returns>
public static Comment[] FetchCommentsByNewest(int Category, int Identifier, int ToSkip, int ToTake)
{
    Comment[] Comments = new Comment[1];

    using (DataClassesDataContext db = new DataClassesDataContext())
    {
        // Loop each comment and insert newest first to array
        var q = (from c in db.tblComments where c.CategoryID == Category amp;amp; c.IdentifierID == Identifier orderby c.PostDate descending select c);
        if(ToSkip > 0)
            q = q.Skip(ToSkip);
        if(ToTake > 0)
            q = q.Take(ToTake);
        Comments = new Comment[q.Count()];
        int i = 0;
        foreach (var Rec in q)
        {

            i  ;
        }
    }

    return Comments;
}
  

Ответ №1:

Вы всегда можете обойти это, изменив код на этот:

 var q = (
   from c in db.tblComments 
   where c.CategoryID == Category amp;amp; c.IdentifierID == Identifier 
   orderby c.PostDate descending select c
)
.Skip(ToSkip > 0 ? ToSkip : 0)
.Take(ToTake > 0 ? ToTake : int.MaxValue);
  

Ответ №2:

Используйте ту же логику, что и ChrisF, и завершите инструкцию возвращением q .toArray() или, если вам нужен класс модели, например Comment, используйте что-то вроде AutoMapper http://automapper.codeplex.com

или

 return q.select( x=>  new Comment{Name = x.Name, Description = x.Description}).ToArray();
  

Примечание: toArray или ToList() вызовут выполнение запроса.

Комментарии:

1. Как это будет выполняться, если в базе данных миллионы строк?

2. вот почему в большинстве случаев лучше написать представление или сохраненную процедуру. вместо создания объекта, как в моем примере. Если отмечено, вы говорите, что код ChrisF должен быть реализован до моего оператора return. Теперь производительность EF4, Linq-2-SQL — это совсем другая тема.