2013-06-14 3 views
1

В клиентском приложении мне нужно иметь все данные таблицы в памяти. Я часто перечитываю данные из базы данных, чтобы убедиться, что у меня есть последняя. Для того, чтобы избежать чтения всех данных каждый раз, когда я использую RowVersion/столбец Timestamp, чтобы получить только измененные данные:Linq-to-2sql - выбор измененных строк

SELECT ... WHERE CAST(RowVersion AS BIGINT) > @lastReadMaxRowVersion 

Как сделать это в Linq2Sql? Если я изменю тип данных сервера в dbml на BIGINT, я получаю InvalidCastException.

ответ

1

Вы должны сделать что-то подобное, выполнив сравнения объектов System.Data.Linq.Binary, которые представляют значения RowVersion/Timestamp в .NET.

Кроме того, вы на самом деле ничего не собираетесь сравнивать. Хитрость заключается в том, чтобы написать LINQ-запрос, который будет переведен в T-SQL, что делает фактическое сравнение.

Используя метод, называемый Compare, который принимает 2 Binary аргументы, LINQ будет счастливо сгенерировать T-SQL, сравнивающий rowversion поля в базе данных. Он не будет вызывать фактический метод. Он просто используется для создания необходимого SQL.

Вместо того, чтобы хранить последнее значение чтения rowversion как Int64, вы просто храните его как Binary.

private Binary _latestRowVersion = new Binary(new byte[] { 0 }); 

private void Read() 
{ 
    using (var ctx = new DataContext()) 
    { 
     var all = 
      (from c in ctx.Categories 
      where c.RowVersion.Compare(_latestRowVersion) > 0 
      select c).ToList(); 

     if (all.Any()) 
     { 
      _latestRowVersion = 
       all.OrderByDescending(
        p => BitConverter.ToInt64(p.RowVersion.ToArray(), 0)) 
       .First() 
       .RowVersion; 
     } 
    } 
} 

public static class BinaryComparer 
{ 
    public static int Compare(this Binary item1, Binary item2) 
    { 
     throw new NotImplementedException(); 
    } 
} 
Смежные вопросы