Если QueueNumber необходимо сохранить в таблице, я бы настроил его как вычисляемый столбец, чтобы база данных могла управлять его вычислением и обновлять, если изменяются базовые поля.
Если это просто то, что вы хотите представить в пользовательском интерфейсе, то я бы порекомендовал, чтобы модель представления вычислила это.
Сущность может вычислять что-то подобное с помощью атрибута [NotMapped]. Например:
public class Queue
{
public int QueueId { get; set; }
[Required]
public string Name { get; set; }
[NotMapped]
public string QueueNumber
{
get { return string.Format("{0}{1:000}", Service?.ServiceLetter ?? "?", QueueId);
}
[ForeignKey("Service")]
public int ServiceId { get; set; }
public Service Service { get; set; }
}
Проблема с этим подходом состоит в том, что для того, чтобы иметь возможность полагаться на свою Очередь для обнаружения QueueNumber, Очередь должна стремиться загрузить Службу, или вы включаете ленивую загрузку и рискуете снизить производительность по сравнению с наличием Службы == #null и получение исключения или неверного результата QueueNumber. В приведенном выше примере, если Сервис не загружен, вы получите что-то вроде «? 001».
Я предпочитаю использовать ViewModels по ряду причин, включая производительность, безопасность и условия обработки, подобные этим, более аккуратно.
Например, учитывая QueueViewModel как:
[Serializable]
public sealed class QueueViewModel
{
public int QueueId{ get; set; }
public string Name { get; set; }
public string ServiceName { get; set; }
public string ServiceLetter { get; set; }
public string QueueNumber
{
return string.Format("{0}{1:000}", ServiceLetter, QueueId);
}
}
Тогда при чтении данных мы не передаем сущности в представление, мы передаем нашу модель представления ...
var viewModel = context.Queues
.Where(x => x.QueueId == queueId)
.Select(x => new QueueViewModel
{
QueueId = x.QueueId,
Name = x.Name,
ServiceName = x.Service.Name,
ServiceLetter = x.Service.ServiceLetter
}).Single();
return viewModel;
Преимущества этого подхода:
Нам не нужно беспокоиться о быстрой / ленивой загрузке. Запрос извлекает все необходимое, и наша модель представления может вычислить все необходимое из загруженных данных. (Запросы могут также вычислять значения, если хотите, но с осторожностью относитесь к ограничениям в том, что запрос должен иметь возможность переходить на SQL, поэтому никаких пользовательских функций и т. Д.)
Производительность улучшена, так как запрос возвращает только необходимые данные, а не целые графы сущностей, и без лишних хитов отложенной загрузки.
Безопасность улучшена, мы предоставляем клиенту не больше данных, чем ожидается / необходимо, и мы не открываем дверь для «ленивых» обновлений, когда сущности присоединяются к контексту и сохраняются без надлежащей проверки.