首页 > 解决方案 > ASP.NET MVC 自动生成整数

问题描述

美好的一天,这里是一位真正的新手开发人员。

我有一个表单,它有一个“QueueNumber”实体有人可以告诉我如何编码,以便当我保存我的表单时它会自动生成 QueueNumber + 前缀,顺便说一句,我的前缀实体在另一个类中

public class Queue
{
    public int QueueId { get; set; }
    [Required]
    public string Name { get; set; }
    public string QueueNumber

    public int ServiceId { get; set; }

    public Service Service { get; set; }
}

-

public class Service
{
    public int ServiceId { get; set; }

    [Display(Name = "Service Name")]
    public string ServiceName { get; set; }

    [Display(Name = "Service Letter")]
    public string ServiceLetter { get; set; }

    [Display(Name = "Status")]
    public bool? Status { get; set; }

    [Display(Name = "Assigned Location")]
    public int? LocationId { get; set; }


    public virtual Location Location { get; set; }
    public virtual ICollection<Customer> Customer { get; set; }
}

数据库中的结果: 1. A001 2. A002 3. A003

我只想能够自动生成一个队列号,当我保存在数据库中时,它就像 A = Service Letter 和 001 = QueueNumber。谢谢

标签: asp.netasp.net-mvcentity-frameworkentity-framework-6entity-framework-4

解决方案


如果 QueueNumber 需要持久化到表中,那么我会将其设置为计算列,以便数据库可以管理计算它并在基础字段更改时更新它。

如果它只是您想在 UI 中表示的东西,那么我建议让视图模型计算它。

实体可以使用 [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”的东西。

出于多种原因,我更喜欢使用 ViewModel,包括性能、安全性和更干净的处理条件。

例如,给定一个 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;

这种方法的好处:

  1. 我们不必担心急切/延迟加载。查询获取所需的所有内容,我们的视图模型可以从加载的数据中计算所需的任何内容。(如果您愿意,查询也可以计算值,但要注意查询必须能够转到 SQL 的限制,因此没有用户函数等)

  2. 由于查询只返回所需的数据而不是整个实体图,因此性能得到了提高,并且没有延迟加载命中。

  3. 安全性得到了改进,我们不会向客户端公开比预期/需要更多的数据,并且我们不会为实体附加到上下文并在没有适当验证的情况下保存的“惰性”更新打开大门。


推荐阅读