044 Lookup resource without Service bus - chempkovsky/CS82ANGULAR GitHub Wiki

Notes

  • It is possible to create Lookup resource without using Service bus.
    • In such a case, any modification of the Lookup resource tables will be done in synchronous(!!!) mode.
      • it may be useful for the UI testing (the testing of the Angular project)
  • In this article we describe how to generate the code for synchronous(!!!) mode.

Steps required to accomplish the task

Entities

  • read the article 034
  • we have created three Entities and each file has code like below.
#if (!NOTMODELING)
...
#endif
  • it means, when modeling mode is off, the definition of these three entities will be removed from the project. But we need them event if modeling mode is off. On the other hand, in the production mode extra foreign keys must be removed from the project.
    • Reminder:
      • When MODELING MODE is on, LprDivision01 and LprDivision02 tables have a foreign key, which references PhbkDivision-table. These foreign keys must be disabled in the production mode
      • When MODELING MODE is on, LprDivision02 has a foreign key, which references PhbkEnterprise-table. Again, this foreign key must be disabled in the production mode.
  • The solution is pretty simple. The code for these three entities should be as follows
  • We must remove #if (!NOTMODELING)...#endif-operator in the LpdDivision.cs-file
Click to show the code
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace PhBkEntity.PhBk
{
    public class LpdDivision
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [Display(Description = "Row id", Name = "Id of the Row", Prompt = "Enter Row Id", ShortName = "Row Id")]
        [Required]
        public int DivisionNameId { get; set; }

        [Display(Description = "Name of the Enterprise Division", Name = "Name of the Division", Prompt = "Enter Division Name", ShortName = "Division Name")]
        [StringLength(20, MinimumLength = 3, ErrorMessage = "Invalid")]
        [Required]
        public string DivisionName { get; set; } = null!;

        public List<LprDivision01> DivisionRef01 { get; set; } = null!;
        public List<LprDivision02> DivisionRef02 { get; set; } = null!;
    }
}
  • We must conditionally disable only extra foreign keys in the LprDivision01.cs-file
Click to show the code
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace PhBkEntity.PhBk
{
    public class LprDivision01
    {
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        [Display(Description = "Row id", Name = "Id of the Division", Prompt = "Enter Division Id", ShortName = "Division Id")]
        [Required]
        public int DivisionId { get; set; }
#if (!NOTMODELING)
        public PhbkDivision Division { get; set; } = null!;
#endif

        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        [Display(Description = "Row id", Name = "Id of the Division", Prompt = "Enter Division Id", ShortName = "Division Id")]
        [Required]
        public int DivisionNameIdRef { get; set; }

        public LpdDivision DivisionNameDict { get; set; } = null!;
    }
}
  • We must conditionally disable only extra foreign keys in the LprDivision02.cs-file
Click to show the code
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace PhBkEntity.PhBk
{
    public class LprDivision02
    {
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        [Display(Description = "Row id", Name = "Id of the Division", Prompt = "Enter Division Id", ShortName = "Division Id")]
        [Required]
        public int DivisionId { get; set; }
#if (!NOTMODELING)
        public PhbkDivision Division { get; set; } = null!;
#endif
        [Display(Description = "Row id", Name = "Id of the Enterprise", Prompt = "Enter Enterprise  Id", ShortName = "Enterprise Id")]
        [Required]
        public int EntrprsIdRef { get; set; }
#if (!NOTMODELING)
        public PhbkEnterprise Enterprise { get; set; } = null!;
#endif

        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        [Display(Description = "Row id", Name = "Id of the DivisionName Row", Prompt = "Enter DivisionName Row Id", ShortName = "DivisionName Row Id")]
        [Required]
        public int DivisionNameIdRef { get; set; }

        public LpdDivision DivisionNameDict { get; set; } = null!;

    }
}

DbContext

DbSets

  • DbSet<LpdDivision> LpdDivisionDbSet, DbSet<LprDivision01> LprDivision01DbSet and DbSet<LprDivision02> LprDivision02DbSet must be available when modeling mode is off.
  • we must replace the code
Click to show the code
#if (!NOTMODELING)
        public DbSet<LpdDivision> LpdDivisionDbSet {
            get => Set<LpdDivision>();

        }

        public DbSet<LprDivision01> LprDivision01DbSet {
            get => Set<LprDivision01>();

        }

        public DbSet<LprDivision02> LprDivision02DbSet {
            get => Set<LprDivision02>();

        }
#endif
  • with the code
Click to show the code
        public DbSet<LpdDivision> LpdDivisionDbSet {
            get => Set<LpdDivision>();

        }

        public DbSet<LprDivision01> LprDivision01DbSet {
            get => Set<LprDivision01>();

        }

        public DbSet<LprDivision02> LprDivision02DbSet {
            get => Set<LprDivision02>();

        }

Foreign and Primary keys

  • As it was mentioned above foreign keys which reference LpdDivision must be available in production mode

  • Primary and Unique keys must be available in production mode

  • we must replace the code

Click to show the code
...
#if (!NOTMODELING)
            modelBuilder.Entity<LprDivision02>().HasKey(p => new { p.EntrprsIdRef, p.DivisionNameIdRef, p.DivisionId });
            modelBuilder.Entity<LprDivision01>().HasKey(p => new { p.DivisionNameIdRef, p.DivisionId });
            modelBuilder.Entity<LpdDivision>().HasAlternateKey(p => p.DivisionName).HasName("LpdDivisionNameUk");
            modelBuilder.Entity<LpdDivision>().HasKey(p => p.DivisionNameId);
            modelBuilder.Entity<LprDivision01>().HasOne(d => d.Division)
                .WithMany(m => m.DivisionRefs01)
                .HasForeignKey(d => d.DivisionId)
                .HasPrincipalKey(p => p.DivisionId)
                .IsRequired(true)
                .OnDelete(DeleteBehavior.NoAction);
            modelBuilder.Entity<LprDivision01>().HasOne(d => d.DivisionNameDict)
                .WithMany(m => m.DivisionRef01)
                .HasForeignKey(d => d.DivisionNameIdRef)
                .HasPrincipalKey(p => p.DivisionNameId)
                .IsRequired(true)
                .OnDelete(DeleteBehavior.NoAction);
            modelBuilder.Entity<LprDivision02>().HasOne(d => d.Division)
                .WithMany(m => m.DivisionRefs02)
                .HasForeignKey(d => d.DivisionId)
                .HasPrincipalKey(p => p.DivisionId)
                .IsRequired(true)
                .OnDelete(DeleteBehavior.NoAction);
            modelBuilder.Entity<LprDivision02>().HasOne(d => d.Enterprise)
                .WithMany(m => m.DivisionRefs02)
                .HasForeignKey(d => d.EntrprsIdRef)
                .HasPrincipalKey(p => p.EntrprsId)
                .IsRequired(true)
                .OnDelete(DeleteBehavior.NoAction);
            modelBuilder.Entity<LprDivision02>().HasOne(d => d.DivisionNameDict)
                .WithMany(m => m.DivisionRef02)
                .HasForeignKey(d => d.DivisionNameIdRef)
                .HasPrincipalKey(p => p.DivisionNameId)
                .IsRequired(true)
                .OnDelete(DeleteBehavior.NoAction);
#endif
...
  • with the code
Click to show the code
...
            modelBuilder.Entity<LprDivision02>().HasKey(p => new { p.EntrprsIdRef, p.DivisionNameIdRef, p.DivisionId });
            modelBuilder.Entity<LprDivision01>().HasKey(p => new { p.DivisionNameIdRef, p.DivisionId });
            modelBuilder.Entity<LpdDivision>().HasAlternateKey(p => p.DivisionName).HasName("LpdDivisionNameUk");
            modelBuilder.Entity<LpdDivision>().HasKey(p => p.DivisionNameId);
            modelBuilder.Entity<LprDivision02>().HasOne(d => d.DivisionNameDict)
                .WithMany(m => m.DivisionRef02)
                .HasForeignKey(d => d.DivisionNameIdRef)
                .HasPrincipalKey(p => p.DivisionNameId)
                .IsRequired(true)
                .OnDelete(DeleteBehavior.NoAction);
            modelBuilder.Entity<LprDivision01>().HasOne(d => d.DivisionNameDict)
                .WithMany(m => m.DivisionRef01)
                .HasForeignKey(d => d.DivisionNameIdRef)
                .HasPrincipalKey(p => p.DivisionNameId)
                .IsRequired(true)
                .OnDelete(DeleteBehavior.NoAction);

#if (!NOTMODELING)
            modelBuilder.Entity<LprDivision01>().HasOne(d => d.Division)
                .WithMany(m => m.DivisionRefs01)
                .HasForeignKey(d => d.DivisionId)
                .HasPrincipalKey(p => p.DivisionId)
                .IsRequired(true)
                .OnDelete(DeleteBehavior.NoAction);
            modelBuilder.Entity<LprDivision02>().HasOne(d => d.Division)
                .WithMany(m => m.DivisionRefs02)
                .HasForeignKey(d => d.DivisionId)
                .HasPrincipalKey(p => p.DivisionId)
                .IsRequired(true)
                .OnDelete(DeleteBehavior.NoAction);
            modelBuilder.Entity<LprDivision02>().HasOne(d => d.Enterprise)
                .WithMany(m => m.DivisionRefs02)
                .HasForeignKey(d => d.EntrprsIdRef)
                .HasPrincipalKey(p => p.EntrprsId)
                .IsRequired(true)
                .OnDelete(DeleteBehavior.NoAction);
#endif
...

Views

  • read the article 036
  • As we do not need additional project for the Views, we can generate Views in the PhBkViews-project.

Data Interfaces and Data Classes

  • read the article 037
  • As we do not need additional project for the Views, we can generate Views in the PhBkViews-project.

Helper Class

  • read the article 042
  • As we do not need additional project for the Controllers, we can generate Helper Class in the PhBkControllers-project.

New Version of Web Api service

  • read the article 039
  • We should use DefaultWebApiServiceWithLookUp.Core.cs.t4-script to generate Web Api code.
  • DefaultWebApiServiceWithLookUp.Core.cs.t4-script generates the code which
    • makes direct method calls of the Helper Class
      • So Helper Class which must be already created.
⚠️ **GitHub.com Fallback** ⚠️