В каких таблицах должен быть столбец меток времени? Проверка параллелизма с Entity Framework, XAF, DDD

Я использую Dev Express XAF WinForms для написания ERP-системы.

На практике я обнаружил, что мой DBContext должен иметь DBSet для большинства моих бизнес-объектов.

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

Например, у меня есть

[NavigationItem("Sales")]
public class SalesOrder : BaseSalesHeader 
{
    public SalesOrder()
    {
       Lines = new List<SalesOrderLine>();
    }
    [Aggregated]
    public virtual List<SalesOrderLine> Lines { get; set; }  
}

[NavigationItem("Production")]
 public class SalesOrderLine : BaseSalesProductTransactionLine 
{

    [Browsable(false)]
    [System.ComponentModel.DataAnnotations.Required]  
    [RuleRequiredField(DefaultContexts.Save)]
    [ForeignKey("SalesOrder_Id")]
    public virtual SalesOrder SalesOrder { get; set; }
}

В моем DBContext у меня есть

    public DbSet<SalesOrder> SalesOrders { get; set; }
    public DbSet<SalesOrderLine> SalesOrderLines { get; set; }

В моем OnModelCreating у меня есть

    modelBuilder.Entity<SalesOrder>().HasMany(p => p.Lines).WithRequired(t => t.SalesOrder).WillCascadeOnDelete(true);

Строки заказа на продажу доступны из 2 меню как часть заказа на продажу и как элемент строки заказа на продажу в элементе навигации «Производство».

Я думаю, что у меня должно быть поле метки времени в таблице SalesOrders. Должен ли я также иметь его в таблице SalesOrderLine?

Вот связанный вопрос в Dev Express Support


person Kirsten Greed    schedule 12.03.2017    source источник
comment
Изучение ~vaughnvernon.co/?p=879 и ~msdn.microsoft.com/en-us/library/jj592904(v=vs.113) .aspx   -  person Kirsten Greed    schedule 13.03.2017
comment
msdn.microsoft.com/en-us/library /jj592904(v=vs.113).aspx   -  person Kirsten Greed    schedule 18.03.2017


Ответы (2)


Мы не можем решить за вас, хотите ли вы применять оптимистичный параллелизм (OC) для сущности. Но есть некоторые вещи, которые следует учитывать:

  • Не обязательно верно, что только объекты, которые представлены как DbSet, будут нуждаться в OC. В конце концов, любой сопоставленный объект можно изменить, если он доступен через свойства навигации. SalesOrder выставляет SalesOrderLines своим свойством Line, поэтому во что бы то ни стало вы можете создать некоторый пользовательский интерфейс, который изменяет только SalesOrderLines, в то время как он получает только SalesOrder (включая его строки) в качестве входных данных.
  • В Entity Framework (и других ORM) родитель не помечается как измененный при изменении одного из его дочерних элементов. Если вы сохраните SalesOrder с измененными SalesOrderLine, будут только операторы обновления для строк.

Итак, да, вы, вероятно, также захотите защитить SalesOrderLine с помощью OC. Но также учтите это:

  • ОС не бесплатная. Когда вы добавляете столбец RowVersion* в таблицу (и сопоставляете его как rowversion соответствующим образом), Entity Framework будет считывать его значение после каждой вставки или обновления. Я испытал, что это может значительно снизить производительность в процессах, которые обновляют относительно много записей (EF там все равно не блестит). Кроме того, при возникновении конфликта параллелизма EF считывает текущие значения конфликтующих записей из базы данных.

Я видел приложения, в которых влияние OC на производительность смягчается путем пометки родительского объекта (имеющего OC) как измененного при изменении любого из его дочерних элементов. Я думаю, что это довольно надумано, но это может быть что-то рассмотреть.


* TimeStamp — устаревший тип данных

person Gert Arnold    schedule 18.03.2017
comment
Итак, по ссылке для примера SalesOrderLIne я добавляю свойство byte[] RowVersion { get; набор; } и используйте modelBuilder.Entity‹SalesOrderLine›() .Property(t =› t.RowVersion) .IsRowVersion(); - person Kirsten Greed; 18.03.2017

Любая таблица, которая может быть обновлена ​​более чем одним пользователем одновременно, должна действительно иметь какую-то связанную с ней временную метку. Лично я ставлю временную метку на каждую таблицу, чтобы быть вдвойне уверенным.

Вы можете пометить это поле временной метки атрибутом [Timestamp], и EF автоматически узнает, что с ним делать.

person Daniel Lorenz    schedule 17.03.2017
comment
мне интересно, могу ли я пропустить таблицы, у которых нет DbSet в DbContext, потому что они будут доступны только как часть агрегата. Если совокупный дочерний элемент обновляется, обновляется ли родительская временная метка? Если совокупный дочерний элемент добавляется или удаляется, обновляется ли родительская метка времени? - person Kirsten Greed; 18.03.2017
comment
Нет, временная метка обновляется только для конкретной таблицы. Родитель не будет знать/заботиться о том, чтобы ребенок изменил свои данные. - person Daniel Lorenz; 20.03.2017