Неожиданное двойное предложение WHERE в пакете услуг OrmLite - PullRequest
0 голосов
/ 06 сентября 2018

У нас есть проблема, которая возникает при каждом вызове метода в течение ограниченных периодов времени. Тогда это работает как ожидалось. Проблема в том, что в коде создаются двойные предложения WHERE.

Мы используем Servicestack 4.5.14

Метод, который мы имеем:

protected static void InsertOrUpdate<T>(
    IDbConnection connection,
    T item,
    Expression<Func<T, bool>> singleItemPredicate,
    Expression<Func<T, object>> updateOnlyFields = null)
{
    var type = item.GetType();
    var idProperty = type.GetProperty("Id");
    if (idProperty == null)
    {
        throw new Exception("Cannot insert or update on a class with no ID property");
    }

    var currentId = (int)idProperty.GetValue(item);
    if (currentId != 0)
    {
        throw new Exception("Cannot insert or update with non-zero ID");
    }

    var query = connection.From<T>().Where(singleItemPredicate).WithSqlFilter(WithUpdateLock);

    T existingItem;
    try
    {
        existingItem = connection.Select(query).SingleOrDefault();
        Log.Verbose(connection.GetLastSql);
    }
    catch (SqlException)
    {
        Log.Verbose(connection.GetLastSql);
        throw;
    }

    if (existingItem == null)
    {
        Insert(connection, item);
        return;
    }

    var existingId = (int)idProperty.GetValue(existingItem);
    idProperty.SetValue(item, existingId);

    try
    {
        var affectedRowCount = connection.UpdateOnly(item, onlyFields: updateOnlyFields, where: singleItemPredicate);
        Log.Verbose(connection.GetLastSql);

        if (affectedRowCount != 1)
        {
            throw new SwToolsException("Update failed");
        }
    }
    catch (SqlException)
    {
        Log.Verbose(connection.GetLastSql);
        throw;
    }
} 

Когда все это работает, пример вывода из журналов может быть:

ВЫБЕРИТЕ «Id», «Приложение», «Имя хоста», «LastContact», «Версия», «ToolState», «ServerState» ОТ "ca". "ExecutionHost" WITH (UPDLOCK) WHERE ("Имя хоста" = @ 0)

ОБНОВЛЕНИЕ "ca". "ExecutionHost" SET "LastContact" = @ LastContact, "Version" = @ Version, "ToolState" = @ ToolState, "ServerState" = @ ServerState WHERE ("Hostname" = @ 0)

При сбое вывод (тот же сеанс, только через несколько секунд) был:

ВЫБЕРИТЕ «Id», «Приложение», «Имя хоста», «LastContact», «Версия», «ToolState», «ServerState» ОТ "ca". "ExecutionHost" WITH (UPDLOCK) WHERE ("Имя хоста" = @ 0)

ОБНОВЛЕНИЕ "ca". "ExecutionHost" SET "LastContact" = @ LastContact, "Version" = @ Version, "ToolState" = @ ToolState, "ServerState" = @ ServerState ГДЕ "LastContact" = @ LastContact, "Version" = @ Version, "ToolState" = @ ToolState, "ServerState" = @ ServerState WHERE ("Имя хоста" = @ 0)

Жирным шрифтом выделено дополнение к SQL, которое делает вызов неудачным. Кажется, что он добавляет дополнительное предложение WHERE с содержимым из предложения SET.

Мы уже некоторое время отлаживали это, и на самом деле не знаем, находится ли проблема на «нашей» стороне или в Servicetack.

Есть идеи, где продолжить?

...