Entity Framework, измените столбец на доступный только для чтения

#asp.net #sql-server-2005 #entity-framework #entity-framework-4

#asp.net #sql-server-2005 #entity-framework #entity-framework-4

Вопрос:

Я использую .NET 4.0, Entity Framework 4 и SQL Server 2005.

У меня есть существующая модель EF. У одной из сущностей с именем Order есть столбец с именем Name (varchar 255), в котором указан уникальный ключ.

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

Требования изменились таким образом, что теперь значение этого столбца должно вычисляться при первом создании заказа и никогда не изменяться впоследствии. Вычисление включает в себя подсчет количества существующих заказов, которые имеют переменную поля (varchar 255) с одинаковым значением. Например:

 int count = this.Orders.Where(o => o.VariableNumber == variableNumber).Count();
  count;
return string.Format("{0}-{1:000}", variableNumber, count);
  

Мой вопрос заключается в следующем: куда мне поместить эту логику, чтобы гарантировать, что Имя вычисляется при первом создании заказа?

Спасибо.

Ответ №1:

Один из подходов заключается в выполнении этого в триггере базы данных. Другой подход делает это в переопределенном SaveChanges :

 public override void SaveChanges()
{
    var orders = context.ObjectStateManager
                        .GetObjectStateEntries(EntityState.Added)
                        .Select(e => e.Entity)
                        .OfType<Order>();

    if (orders.Count() > 0)
    {
        // serialized transaction to lock records so
        // that concurrent thread can't insert orders
        // with the same name while this threads preparing
        // its orders
        using (var scope = new TransactionScope())
        {
            // Here get current counts for variable numbers

            foreach (var order in orders)
            {
                order.Name = ...;
            } 

            base.SaveChanges();
            scope.Complete();
        }
    }
    else
    {
        // saving changes with default transaction
        base.SaveChanges();
    }
}