yarn knex migrate:make
, yarn knex migrate:latest
, etc, and they all have a counterpart in .net framework.
If our application is chosen to be "NO AUTHETICATION", we need to add a class file written as:1 2 3 4 5 6 7 8 | using System.Data.Entity public class MyDbContext : DbContext { public MyDbContext() { } } |
1 | enable-migrations |
1 2 | Checking if the context targets an existing database... Code First Migrations enabled for project ReallyTrue. |
1 2 3 4 5 | < add name="TestMigration5" connectionString="Data Source=DESKTOP-LNOHRJR; Initial Catalog=aspnet-TestMigration5-20190818112608; Integrated Security=True; user ID=YOURID;password =YOURPW" providerName="System.Data.SqlClient" /> |
2 Setup a Table with Auto-Incremental Primary key. Now our database just consists of tables of asp.users information, in order to add additional entity table (for example, we add our "Customers", "Product", etc, tables) we need to refer them in identiyModel.cs by adding:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public class ApplicationDbContext : IdentityDbContext<Applicationuser> { public DbSet<Customer> Customers { get ; set ; } public ApplicationDbContext() : base ( "DefaultConnection" , throwIfV1Schema: false ) { } public static ApplicationDbContext Create() { return new ApplicationDbContext(); } } |
add-migration AddCustomer
in package console, we get1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | using System; using System.Data.Entity.Migrations; namespace ReallyTrue.Migrations { public partial class AddCustomer : DbMigration { public override void Up() { CreateTable( "dbo.Customers" , c => new { Id = c.Int(nullable: false , identity: true ), Name = c.String(), }) .PrimaryKey(t => t.Id); } public override void Down() { DropTable( "dbo.Customers" ); } } } |
update-database
in the console. A natural question: is the id set to be auto-increment? The answer is positive:3 Foreign Key. Next for each customer we want to add a property called membership. memberships have different prices, each membership has a duration, and each membership also has a discount rate. Moreover, customer will have just one membership type. We construct a membership type as follows:
1 2 3 4 5 6 7 8 9 10 | namespace ReallyTrue.Models { public class MembershipType { public int Id { get ; set ; } public short SignUpFee { get ; set ; } public byte DurationInMonths { get ; set ; } public byte DiscountRate { get ; set ; } } } |
1 2 3 4 5 6 7 8 9 10 11 | using ReallyTrue.Models; namespace ReallyTrue.Models { public class Customer { public int Id { get ; set ; } public string Name { get ; set ; } public int MembershipTypeId { get ; set ; } } } |
Type + Id
naming convention will be automatically identified as a foreign key.By the way, since a customer may not subscribe to any membership, I have to alter the table as follows:
and out of expected, by typing
add-migration ChangeMembershipIdTobeNullable,
instead of giving me an error, entity framework do all the subtle work for me!!!!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | using System.Data.Entity.Migrations; namespace ReallyTrue.Migrations { public partial class ChangeMembershipIdTobeNullable : DbMigration { public override void Up() { DropForeignKey( "dbo.Customers" , "MembershipTypeId" , "dbo.MembershipTypes" ); DropIndex( "dbo.Customers" , new [] { "MembershipTypeId" }); AlterColumn( "dbo.Customers" , "MembershipTypeId" , c => c.Int()); CreateIndex( "dbo.Customers" , "MembershipTypeId" ); AddForeignKey( "dbo.Customers" , "MembershipTypeId" , "dbo.MembershipTypes" , "Id" ); } public override void Down() { DropForeignKey( "dbo.Customers" , "MembershipTypeId" , "dbo.MembershipTypes" ); DropIndex( "dbo.Customers" , new [] { "MembershipTypeId" }); AlterColumn( "dbo.Customers" , "MembershipTypeId" , c => c.Int(nullable: false )); CreateIndex( "dbo.Customers" , "MembershipTypeId" ); AddForeignKey( "dbo.Customers" , "MembershipTypeId" , "dbo.MembershipTypes" , "Id" , cascadeDelete: true ); } } } |
yarn knex seed:run
, we directly insert value via migration as follows: first we run add-migration PopulateMembershipTypes
and in that migration file we write1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | using System; using System.Data.Entity.Migrations; namespace ReallyTrue.Migrations { public partial class PopulateMembershipTypes : DbMigration { public override void Up() { Sql( "INSERT INTO MembershipTypes (SignUpFee, DurationInMonths, DiscountRate) VALUES (0,0,0)" ); Sql( "INSERT INTO MembershipTypes (SignUpFee, DurationInMonths, DiscountRate) VALUES (30,1,10)" ); Sql( "INSERT INTO MembershipTypes (SignUpFee, DurationInMonths, DiscountRate) VALUES (90,3,15)" ); Sql( "INSERT INTO MembershipTypes (SignUpFee, DurationInMonths, DiscountRate) VALUES (300,12,20)" ); } public override void Down() { } } } |
5 DataAnnotation. Unforturnately some data types are nullable by default, we need annotation (writing attribute) to enforce restriction to these data type:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | using ReallyTrue.Models; using System.ComponentModel.DataAnnotations; namespace ReallyTrue.Models { public class Customer { public int Id { get ; set ; } [Required] [StringLength(255)] public string Name { get ; set ; } public bool IsSubscribedToNewsletter { get ; set ; } public MembershipType MembershipType { get ; set ; } public int ? MembershipTypeId { get ; set ; } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | public class HomeController : Controller { private ApplicationDbContext _context; public HomeController() { _context = new ApplicationDbContext(); } protected override void Dispose( bool disposing) { _context.Dispose(); } public ActionResult Customer() { ViewBag.title = "Customer" ; ViewBag.Message = "All Customer" ; var customers = _context.Customers.Include( "MembershipType" ).ToList(); return View(customers); } } } |
Include
method will append the associated MembershipType (a list) to customer as a property. For joining multiple tables, seeFinally the following .cshtml
1 2 3 4 5 6 7 8 9 10 11 12 13 | @{ ViewBag.Title = "About" ; } @model List<reallytrue.models.customer> <h2>@ViewBag.Title.</h2> <h3>@ViewBag.Message</h3> <ul> @ foreach (var customer in Model) { <li >@customer.Name with membership of discount rate customer.MembershipType.DiscountRate% </li > } </ul> |
No comments:
Post a Comment