2017-01-27 3 views
1

Попытка реализовать оптимистичный параллелизм с Entity Framework 6 (подход Designer First) и базу данных Oracle (версия 12).Оптимистичный параллелизм с платформой Entity Framework и ORACLE

SQL Server имеет атрибут RowVersion, который может использоваться для отслеживания изменений, не может найти какой-либо аналогичный атрибут в Oracle.

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

Благодаря

+1

Возможный дубликат [SQL Server: эквивалент RowVersion в Oracle] (http://stackoverflow.com/questions/20487657/sql-server-rowversion-equivalent-in-oracle) – Fran

+0

Можете ли вы рассказать о том, чего вы пытаетесь достичь? Oracle обладает очень сложным и в значительной степени автоматическим механизмом параллелизма. – BobC

ответ

2

Конечно, есть способ сделать это без триггера. Выполнение этого без триггера будет работать с любой базой данных, поддерживаемой провайдерами Entity Framework ...

К сожалению, я не уверен в отношении подхода Designer First, но с Code First вы можете сделать это так (это, вероятно, похоже на Designer First, возможно, используя частичный класс). Если смотреть вперёд, если это возможно, вы должны использовать Code First, потому что это поддерживается только новым Entity Framework Core.

Модель:

public abstract class ConcurrencyTracker 
{ 
    [ConcurrencyCheck] 
    public long LastChange { get; set; } 

    [NotMapped] 
    public DateTime LastChangeTime 
    { 
     set 
     { 
      long timestamp = value.Ticks - new DateTime(1970, 1, 1).Ticks; 
      timestamp = timestamp/TimeSpan.TicksPerSecond; 
      LastChange = timestamp; 
     } 
    } 
} 

public class Product : ConcurrencyTracker 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

Контекст:

public override int SaveChanges() 
{ 
    var currentTime = DateTime.Now; 

    var changed = ChangeTracker.Entries<ConcurrencyTracker>().Where(c => c.State != EntityState.Unchanged); 
    if (changed != null) 
    { 
     foreach (var item in changed) 
     { 
      item.Entity.LastChangeTime = currentTime; 
     } 
    } 
    return base.SaveChanges(); 
} 

EF будет включать в себя столбец LastChange во всех обновлений модели продукта так что оптимистичный параллелизм.

+0

Можете ли вы объяснить на английском языке, в отличие от кода, что вы пытаетесь сделать? – BobC

+1

Единственное, что «особенное» здесь заключается в том, что мы обновляем столбец LastChange, а не позволяем базе данных обновлять его. Это все. Не стесняйтесь попробовать ... –

+1

ConcurrencyTracker - это специальный абстрактный класс. Я создал его и дал ему это имя. Вы можете переименовать его так или иначе, как вам нравится. Таким образом, он доступен. Попробуйте вставить весь этот код в новое тестовое приложение Console и заставить его работать, а затем использовать его в существующем проекте. –

0

Вы можете использовать псевдо-столбец ORA_ROWSCN в Oracle, а не создавать и поддерживать метку времени. Вам нужно будет создать таблицы с включенными ROWDEPENDENCIES.

+0

Из того, с чем я столкнулся, ORA_ROWSCN недоступен на уровне строки, чтобы использовать его через Entity Framework. – skjagini

+0

ORA_ROWSCN - псевдо-столбец, поэтому он доступен на уровне строк. Там, где вы можете быть смущены, SCN (System Change Number) действительно обновляется только после изменения блоков. Однако, включив ROWDEPENDENCIES, он будет отслеживать изменения уровня строки. Что касается Entity Framework, я понятия не имею, что это такое;) – BobC