【问题标题】:ASP.NET MVC Auto generate integer numberASP.NET MVC 自动生成整数
【发布时间】:2019-07-27 15:42:37
【问题描述】:

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

我有一个表单,它有一个“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.net asp.net-mvc entity-framework entity-framework-6 entity-framework-4


    【解决方案1】:

    如果 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”的东西。

    出于多种原因,我更喜欢使用 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;
    

    这种方法的好处:

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

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

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

    【讨论】:

    • 我还需要保存Queue实体的数据,因为我稍后要检索它,可以吗?
    • 是的,当您调用更新时,视图模型(或单独的更新视图模型)将具有定位实体所需的 ID,以及验证和更新的字段。您应该针对当前会话的用户声明 ID(他们是否更新了他们有权访问的数据),并且在加载与 ID 关联的实体并应用更新之前,这些值是有效的。还要检查时间戳,以防数据自读取后发生更改。读取通常比写入更常见,因此调整读取性能并按 ID 拉取实体以快速进行更新是有意义的。
    • 视图模型只是用来显示你想要的数据吧? “如果它只是你想在 UI 中表示的东西,那么我建议让视图模型计算这个”。 -@史蒂夫·派
    • 这是视图对模型的表示。这可以包括计算值,以及示例中的展平数据。视图不需要整个“服务”,只需要几个值。这会减少向客户端发送不必要的数据,并且不会让某人访问有关您的架构的额外信息。 (FK 和其他未渲染但仍可通过调试工具访问的细节。)
    • 你能给我一个你给我的示例视图代码吗?使用 QueueViewModel
    猜你喜欢
    • 2011-02-09
    • 1970-01-01
    • 1970-01-01
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    • 2020-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多