Преобразование кода SQL с помощью Row_Number() в код LINQ C#

В основном я перечисляю все серверы с именем «ServerName» в порядке создания DESC. Если, например, у меня их 50, мне нужно получить список из 40 идентификаторов серверов, чтобы их можно было удалить; таким образом я сохраняю только последние 10 созданных записей (серверов). Вот простой код SQL:

  Delete ContosoServers Where serverId In
  (
    Select
    serverId
    From
    (
      Select 
        serverId
        ,row_number() Over(Order By created desc) as recordNumber
      From 
        UDS.ContosoServers
      Where 
        name = 'ServerName'
    ) ServerRecords
    Where recordNumber > 10
  )

Я думаю, мне нужно будет создать список какого-то анонимного типа (serverId, recordNumber). Как только я получу это, я могу просто просмотреть список от 11 до 50 и удалить все записи серверов, сохраняя от 1 до 10, которые являются последними.

Я придумал это решение, но я думаю, что это слишком много кода. В SQL это очень просто, но в LINQ, похоже, требуется больше работы. Я просто пытаюсь избежать всех этих циклов, вот он:

    private static void DeleteOldRecords(string serverName)
    {
        const int numberOfRecordsToKeep = 10;

        using (var context = new MyContext())
        {
            var servers = context.ContosoServers
                                .Where(n => n.name == serverName)
                                .OrderByDescending(o => o.created)
                                .Select(s => new { s.serverId }).ToList();

            //skip the first 10 rows and delete the rest 11,20...
            int i = 0;
            foreach (var s in servers)
            {
                if (i > numberOfRecordsToKeep - 1)
                {
                    //delete row
                    var entityToDelete = context.ContosoServers.Find(s.serverId);
                    if (context.Entry(entityToDelete).State == EntityState.Detached)
                    {
                        context.ContosoServers.Attach(entityToDelete);
                    }
                    context.ContosoServers.Remove(entityToDelete);
                }
                i++;
            }
            context.SaveChanges();
        }

Любые идеи о том, как улучшить это? это не кажется "элегантным" :-)

Спасибо


person Max    schedule 08.01.2014    source источник
comment
Это может помочь - из связанного списка: stackoverflow.com/a/1183599/745969   -  person Tim    schedule 08.01.2014


Ответы (1)


Предполагая, что вы используете LINQ to SQ, попробуйте код ниже

Контекст DataClasses1DataContext = new DataClasses1DataContext();

        var d = (from s in context.ContosoServers
                 orderby s.created descending 
                 select s).Take(10);

        context.samples.DeleteAllOnSubmit(d);
        context.SubmitChanges();
person CSharped    schedule 08.01.2014
comment
это фактически удалит 10 последних строк, которые я хочу сохранить. - person Max; 08.01.2014
comment
orderby s.created (не по убыванию) и Skip(10). - person Gert Arnold; 09.01.2014
comment
Я думаю, что ответом будет порядок с помощью DESC и skip(10), не так ли? Я хочу сохранить 10 последних строк и удалить все остальное - person Max; 09.01.2014