I am using Dev Express XAF WinForms to write an ERP system.
In practice I have found that my DBContext needs to have a DBSet for most of my business objects.
I am trying to figure out which tables should have a timestamp column for optimistic concurrency purposes.
For example I have
[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; }
}
In my DBContext I have
public DbSet<SalesOrder> SalesOrders { get; set; }
public DbSet<SalesOrderLine> SalesOrderLines { get; set; }
In my OnModelCreating I have
modelBuilder.Entity<SalesOrder>().HasMany(p => p.Lines).WithRequired(t => t.SalesOrder).WillCascadeOnDelete(true);
Sales Order Lines are accessible from 2 Menus As part of a Sales Order, and as a Sales Order Line Item under the Production navigation item.
I think I should have the timestamp field in the SalesOrders table. Should I also have it in the SalesOrderLine table ?
Here is the linked question at Dev Express Support
Whether or not you want to apply optimistic concurrency (OC) for an entity is something we can't decide for you. But there are some things to consider:
DbSet
will need OC. After all, any mapped entity can be changed when it's reachable through navigation properties. SalesOrder
exposes SalesOrderLine
s by its Line
property, so by all means you can create some UI that only modifies SalesOrderLine
s while it only receives a SalesOrder
(including its lines) as input.SalesOrder
with modified SalesOrderLine
s, there will only be update statements for the lines.So, yes, you probably want to protect SalesOrderLine
by OC as well. But also consider this:
RowVersion
* column to a table (and map it as rowversion appropriately), Entity Framework will read its value after each insert or update. I've experienced that this may considerably harm performance in processes that update relatively many records (EF doesn't shine there anyway). Also, when a concurrency conflict occurs, EF will read the current values of the conflicting record(s) from the database.I've seen applications where the performance impact from OC is mitigated by marking a parent object (having OC) as modified when any of its children is modified. I think that's rather contrived, but it may be something to consider.
* TimeStamp
is a deprecated data type