Запрос столбца метки времени из LINQ to SQL - PullRequest
7 голосов
/ 14 февраля 2009

В моей таблице есть столбец отметки времени с именем «RowVer», который LINQ сопоставляет с типом System.Data.Linq.Binary. Этот тип данных кажется мне бесполезным, потому что (если я что-то упускаю) я не могу делать такие вещи:

// Select all records that changed since the last time we inserted/updated.
IEnumerable<UserSession> rows = db.UserSessions.Where
( usr => usr.RowVer > ???? );

Итак, одно из решений, которые я рассматриваю, - это добавить новый «вычисляемый столбец» под названием RowTrack, который определен в SQL следующим образом:

CREATE TABLE UserSession
(
RowVer timestamp NOT NULL,
RowTrack  AS (convert(bigint,[RowVer])),
-- ... other columns ...
)

Это позволяет мне запрашивать базу данных так, как я хочу:

// Select all records that changed since the last time we inserted/updated.
IEnumerable<UserSession> rows = db.UserSessions.Where
( usr => usr.RowTrack > 123456 );

Это плохой способ делать вещи? Насколько эффективен запрос к вычисляемому столбцу? Есть ли лучший обходной путь?

Кроме того, я разрабатываю Sql Server 2000 для максимальной обратной совместимости, но я могу убедить босса сделать 2005 наименьшим общим знаменателем.

Ответы [ 4 ]

9 голосов
/ 30 сентября 2010

AS Диего Фрата обрисовывает в общих чертах в этом посте есть хак, позволяющий запрашивать метки времени из LINQ.

Хитрость заключается в определении метода сравнения , который принимает два System.Data.Linq.Binary параметров

public static class BinaryComparer
{
 public static int Compare(this Binary b1, Binary b2)
 {
 throw new NotImplementedException();
 }
}

Обратите внимание, что функцию не нужно реализовывать, важно только ее имя ( Compare ).

И запрос будет выглядеть примерно так:

Binary lastTimestamp = GetTimeStamp();
var result = from job in c.GetTable<tblJobs>
             where BinaryComparer.Compare(job.TimeStamp, lastTimestamp)>0
             select job;

(Это в случае job.TimeStamp> lastTimestamp)

EDIT : См. ответ Рори Маклауда о реализации метода, если он нужен для работы вне SQL.

6 голосов
/ 14 февраля 2009

SQL Server «отметка времени» является лишь индикатором того, что запись изменилась, на самом деле она не является представлением даты / времени. (Хотя предполагается увеличивать каждый раз при изменении записи в БД,

Остерегайтесь того, что оно вернется к нулю (не очень часто, по общему признанию), поэтому единственный безопасный тест - это если значение изменилось, а не если оно больше некоторого произвольного предыдущего значения.

Вы можете передать значение столбца TimeStamp в веб-форму, а затем, когда оно будет отправлено, посмотреть, отличается ли TimeStamp от формы от значения в текущей записи - если оно отличается, кто-то другой изменил и сохранил запись в промежутке.

4 голосов
/ 14 февраля 2009

// Выбрать все записи, которые изменились с момента последнего добавления / обновления.

Есть ли лучший обходной путь?

Почему бы не иметь два столбца, один для созданной даты, другой для последней измененной даты. Я бы сказал, что это более традиционный способ справиться с этим сценарием.

2 голосов
/ 21 июля 2012

Исходя из ответа jaraics , вы также можете предоставить реализацию метода Compare, которая позволит ему работать вне запроса:

public static class BinaryExtensions
{
    public static int Compare(this Binary b1, Binary b2)
    {
        if (b1 == null)
            return b2 == null ? 0 : -1;

        if (b2 == null)
            return 1;

        byte[] bytes1 = b1.ToArray();
        byte[] bytes2 = b2.ToArray();
        int len = Math.Min(bytes1.Length, bytes2.Length);
        int result = memcmp(bytes1, bytes2, len);

        if (result == 0 && bytes1.Length != bytes2.Length)
        {
            return bytes1.Length > bytes2.Length ? 1 : -1;
        }

        return result;
    }

    [DllImport("msvcrt.dll")]
    private static extern int memcmp(byte[] arr1, byte[] arr2, int cnt);
}

Использование memcmp было взято из этого ответа к вопросу о сравнении байтовых массивов. Если массивы не имеют одинаковую длину, но более длинный массив начинается с тех же байтов, что и более короткий массив, считается, что более длинный массив больше, чем более короткий, даже если все дополнительные байты равны нулю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...