Bài 9 Làm việc với Database trên ASP.NET Core

Đối tượng RazorPagesMovieContext xử lý tác vụ kết nối với cơ sở dữ liệu và mapping các đối tượng Movie vào các bản ghi cơ sở dữ liệu. Database Context được đăng ký với bộ chứa Dependency Injection trong phương thức ConfigureService trong Startup.cs:

// This method gets called by the runtime. 
// Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        // This lambda determines whether user consent for non-essential cookies is 
        // needed for a given request.
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

    services.AddDbContext<RazorPagesMovieContext>(options =>
      options.UseSqlServer(
          Configuration.GetConnectionString("RazorPagesMovieContext")));
}

Khác với phiên bản ASP.NET MVC sử dụng file web.config thì asp.net core sử dụng file json  appsettings.json  để lưu kết nối và đọc ConnectionString từ đây. Tên database Database=RazorPagesMovieContext-1234 sẽ khác mỗi khi bạn tạo một project mới.

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "RazorPagesMovieContext": "Server=(localdb)\\mssqllocaldb;Database=RazorPagesMovieContext-1234;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

Khi ứng dụng được triển khai đến máy chủ Test hoặc Product, một biến môi trường có thể được sử dụng để đặt chuỗi kết nối thành máy chủ cơ sở dữ liệu thực hay test.

SQL Server Express LocalDB

LocalDB là phiên bản gọn nhẹ của công cụ cơ sở dữ liệu SQL Server Express được nhắm mục tiêu phát triển chương trình. LocalDB bắt đầu theo yêu cầu và chạy trong chế độ người dùng, do đó không có cấu hình phức tạp. Theo mặc định, cơ sở dữ liệu LocalDB tạo các tệp * .mdf trong thư mục C:/Users/<user/>

Từ menu View, mở SQL Server Object Explorer (SSOX).

ssox.png

Click chuột phải vào bảng Movie  và chọn View Designer:

design

dv.png

Lưu ý biểu tượng phím bên cạnh ID. Theo mặc định, EF tạo một thuộc tính có tên ID cho khóa chính.

Nhấp chuột phải vào bảng Movie và chọn ViewData:

vd22

Seed the database (tạo dữ liệu khi chạy ứng dụng)

Tạo class SeedData  trong thư mục Models. 

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Linq;

namespace RazorPagesMovie.Models
{
    public static class SeedData
    {
        public static void Initialize(IServiceProvider serviceProvider)
        {
            using (var context = new RazorPagesMovieContext(
                serviceProvider.GetRequiredService<
                    DbContextOptions<RazorPagesMovieContext>>()))
            {
                // Look for any movies.
                if (context.Movie.Any())
                {
                    return;   // DB has been seeded
                }

                context.Movie.AddRange(
                    new Movie
                    {
                        Title = "When Harry Met Sally",
                        ReleaseDate = DateTime.Parse("1989-2-12"),
                        Genre = "Romantic Comedy",
                        Price = 7.99M
                    },

                    new Movie
                    {
                        Title = "Ghostbusters ",
                        ReleaseDate = DateTime.Parse("1984-3-13"),
                        Genre = "Comedy",
                        Price = 8.99M
                    },

                    new Movie
                    {
                        Title = "Ghostbusters 2",
                        ReleaseDate = DateTime.Parse("1986-2-23"),
                        Genre = "Comedy",
                        Price = 9.99M
                    },

                    new Movie
                    {
                        Title = "Rio Bravo",
                        ReleaseDate = DateTime.Parse("1959-4-15"),
                        Genre = "Western",
                        Price = 3.99M
                    }
                );
                context.SaveChanges();
            }
        }
    }
}

Nếu có bất kỳ movie trong DB, Việc khởi tạo seed trả về và không có movie nào được thêm vào.

if (context.Movie.Any())
{
    return;   // DB has been seeded.
}

Thêm trình khởi tạo seed
Trong Program.cs, sửa đổi phương thức Main để làm như sau:

Lấy một instance DB context từ dependency injection container.
Gọi phương thức seed, chuyển đến context.
Dispose context khi phương thức seed hoàn thành.
Đoạn mã sau hiển thị tệp Program.cs được cập nhật.

using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using RazorPagesMovie.Models;
using System;
using Microsoft.EntityFrameworkCore;

namespace RazorPagesMovie
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var host = CreateWebHostBuilder(args).Build();

            using (var scope = host.Services.CreateScope())
            {
                var services = scope.ServiceProvider;

                try
                {
                    var context=services.
                        GetRequiredService<RazorPagesMovieContext>();
                    context.Database.Migrate();
                    SeedData.Initialize(services);
                }
                catch (Exception ex)
                {
                    var logger = services.GetRequiredService<ILogger<Program>>();
                    logger.LogError(ex, "An error occurred seeding the DB.");
                }
            }

            host.Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>();
    }
}

Một ứng dụng production sẽ không gọi Database.Migrate. Nó được thêm vào mã trước để ngăn ngoại lệ sau khi Cập nhật cơ sở dữ liệu chưa được chạy:

SqlException: Không thể mở cơ sở dữ liệu “RazorPagesMovieContext-21” theo yêu cầu đăng nhập. Việc đăng nhập thất bại. Đăng nhập thất bại cho người dùng ‘user name’.

Test app

Xóa tất cả các bản ghi trong DB. Bạn có thể làm điều này với các liên kết xóa trong trình duyệt hoặc từ SSOX

Buộc ứng dụng khởi tạo (gọi các phương thức trong lớp Khởi động) để phương thức seed chạy. Để bắt buộc khởi tạo, IIS Express phải được dừng và khởi động lại. Bạn có thể làm điều này với bất kỳ phương pháp nào sau đây:

Nhấp chuột phải vào biểu tượng khay hệ thống IIS Express trong vùng thông báo và nhấn Thoát hoặc Dừng trang:

iisexicon

stopiis.png

Ứng dụng hiển thị dữ liệu đã seed:

m55.png

Bài 8: CRUD cho Razor Pages trong ASP.NET Core

Trang: Create, Delete, Details, và Edit

Kiểm tra trang Pages/Movies/Index.cshtml.cs

phương thức trong PageModel

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Pages.Movies
{
    public class IndexModel : PageModel
    {
        private readonly RazorPagesMovie.Models.RazorPagesMovieContext _context;

        public IndexModel(RazorPagesMovie.Models.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IList<Movie> Movie { get;set; }

        public async Task OnGetAsync()
        {
            Movie = await _context.Movie.ToListAsync();
        }
    }
}
Razor page có nguồn gốc từ PageModel. Theo quy ước, class có nguồn gốc PageModel được gọi là <PageName>Model. Hàm constructor sử dụng dependency injection để thêm RazorPagesMovieContext vào page. Tất cả các trang được tạo tự động (scaffolded) theo mô hình này. Xem Asynchronous code để biết thêm thông tin về lập trình không đồng bộ với Entity Framework.

Khi yêu cầu được thực hiện cho trang, phương thức OnGetAsync sẽ trả về danh sách Movies cho Razor page. OnGetAsync hoặc OnGet được gọi trên Razor page để khởi tạo trạng thái cho page. Trong trường hợp này, OnGetAsync lấy danh sách Movies và hiển thị chúng.
Khi OnGet trả về void hoặc OnGetAsync trả về Task, không có phương thức trả về nào được sử dụng. Khi loại trả về là IActionResult hoặc Task<IActionResult>, phải cung cấp câu lệnh trả về. Ví dụ: phương thức OnPostAsync: Pages/Movies/Create.cshtml.cs:

public async Task<IActionResult> OnPostAsync()
{
    if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Kiểm tra trang Pages/Movies/Index.cshtml:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model.Movie) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReleaseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Genre)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            <td>
                <a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
                <a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
                <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Razor có thể chuyển từ HTML sang C # hoặc từ các markup riêng của Razor. Khi một biểu tượng @ được theo sau bởi một từ keyword dành riêng cho Razor, nó sẽ hiểu là Razor-specific markup, nếu không, nó sẽ hiểu là lệnh code bằng C # để xử lý ví dụ như tạo biến trong Razor page.
Lệnh @page trong Razor page làm cho tệp thành action của MVC, có nghĩa là nó có thể xử lý các request. @page phải ở đầu tiên trên một trang. @page là một ví dụ về việc chuyển đổi Razor-specific markup. Xem Razor syntax để biết thêm các cú pháp của razor.
Kiểm tra biểu thức lambda được sử dụng trong HTML Helper sau:

@Html.DisplayNameFor(model => model.Movie[0].Title))

DisplayNameFor HTML Helper sẽ hiển thị Title của movie nhưng sẽ kiểm tra nếu modelmodel.Movie, hoặcmodel.Movie[0] null thì sẽ không hiển thị gì.

Cú pháp @model trong razor page

Khi bạn đẩy dữ liệu từ action trong PageModel qua Razor page thì cần biến để lưu giá trị và sử dụng nó để hiển thị dữ liệu. Khi đó cú pháp

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

cho phép khai báo và gán dữ liệu từ PageModel sang biến Model trong Razor page.
Khi đó để sử dụng dữ liệu ta có thể truy cập như trên trang index.cshtml ví dụ như:
@Html.DisplayNameFor(model => model.Movie[0].Title))
hay
@foreach (var item in Model.Movie)

Trang Layout

Chọn trên menu link (RazorPagesMovieHome, and Privacy). Các page đều có cùng 1 menu. Menu này được viết chung tại file Pages/Shared/_Layout.cshtml . Hãy mở file này ra.

Ta thấy đoạn ký tự đặc biệt @RenderBody() trong html nó cho phép hiển thị các trang khác tại đây khi các trang sử dụng layout này. Các trang khác sẽ thay thế @RenderBody() bằng đoạn html mà nó tạo ra. Từ đó sẽ có html đầy đủ của layout và trang đó.

ViewData và layout

Xem code trong file Pages/Movies/Index.cshtml

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

Đoạn code được in đậm là ví dụ khi code trong C# trong razor page. Trong ký tự { và } được gọi là 1 block code C#. Trong PageModel thường dùng để gán dữ liệu cho ViewData theo dạng key – value. Ví dụ thuộc tính “Title” được thêm vào ViewData. Thuộc tính “Title” sử dụng trong file Pages/Shared/_Layout.cshtml. Cho phép hiển thị tại một số đoạn trong file_Layout.cshtml

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - RazorPagesMovie</title>

    @*Markup removed for brevity.*@

dòng @*Markup removed for brevity.*@
razor sẽ không hiển thị trên page khi chạy ứng dụng mà chỉ hiển thị trong razor page như một comment. Không giống như comment HTML (<! – ->), các comment Razor không được gửi và hiển thị trên client.

Update the layout

Thay đổi title tại thẻ <title> trong layout Pages/Shared/_Layout.cshtml  để hiển thị title cho từng trang mà chỉ cần truyền title vào qua @ViewData[“Title”]

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - Movie</title>

Tìm thẻ a sau:

<a class="navbar-brand" asp-area="" asp-page="/Index">RazorPagesMovie</a>

Thay đổi giá trị thành

<a class="navbar-brand" asp-page="/Movies/Index">RpMovie</a>

Tag helper asp-page=”/Movies/Index” sẽ tạo ra link /Movies/Index trên Razor page.

Layout sẽ được thiết lập tại file Pages/_ViewStart.cshtml

@{
    Layout = "_Layout";
}

Tất cả các view sẽ được thiết lập sử dụng layout này. Nếu muốn sử dụng layout khác trên 1 view nào đó ta chỉ cần set lại layout muốn sử dụng.

Tạo trang Create

kiểm tra file Pages/Movies/Create.cshtml.cs 

// Unused usings removed.
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesMovie.Models;
using System;
using System.Threading.Tasks;

namespace RazorPagesMovie.Pages.Movies
{
    public class CreateModel : PageModel
    {
        private readonly RazorPagesMovie.Models.RazorPagesMovieContext _context;

        public CreateModel(RazorPagesMovie.Models.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IActionResult OnGet()
        {
            return Page();
        }

        [BindProperty]
        public Movie Movie { get; set; }

        public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return Page();
            }

            _context.Movie.Add(Movie);
            await _context.SaveChangesAsync();

            return RedirectToPage("./Index");
        }
    }
}

    
</form> </div> </div> @section Scripts { @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} } ">@page @model RazorPagesMovie.Pages.Movies.CreateModel @{ ViewData["Title"] = "Create"; } <h1>Create</h1> <h4>Movie</h4> <hr /> <div class="row"> <div class="col-md-4"> <form method="post"> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <div class="form-group"> <label asp-for="Movie.Title" class="control-label"></label> <input asp-for="Movie.Title" class="form-control" /> <span asp-validation-for="Movie.Title" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Movie.ReleaseDate" class="control-label"></label> <input asp-for="Movie.ReleaseDate" class="form-control" /> <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Movie.Genre" class="control-label"></label> <input asp-for="Movie.Genre" class="form-control" /> <span asp-validation-for="Movie.Genre" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Movie.Price" class="control-label"></label> <input asp-for="Movie.Price" class="form-control" /> <span asp-validation-for="Movie.Price" class="text-danger"></span> </div> <div class="form-group"> <input type="submit" value="Create" class="btn btn-primary" /> </div> </form> </div> </div> <div> <a asp-page="Index">Back to List</a> </div> @section Scripts { @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} }

Bài 7: Thêm Model vào Razor Pages trong ASP.NET Core

Trong phần này, các lớp được thêm vào để quản lý movies trong database. Các lớp này được sử dụng với Entity Framework Core (EF Core) để làm việc với database. EF Core là object-relational mapping (ORM) framework giúp đơn giản hóa mã truy cập dữ liệu.

Các lớp model được gọi là các lớp POCO (từ “plain-old CLR objects”) vì chúng không có bất kỳ sự phụ thuộc nào vào EF Core. Chúng xác định các thuộc tính của dữ liệu được lưu trữ trong database. view code sample here

Thêm mới 1 data Model

Click chuột phải vào project RazorPagesMovieAdd > New Folder. Đặt tên folder là Models.

Click chuột phải vào Models folder. Chọn Add > Class. Đặt tên class là Movie.

Thêm các thuộc tính sau vào lớp Movie:

using System;
using System.ComponentModel.DataAnnotations;

namespace RazorPagesMovie.Models
{
    public class Movie
    {
        public int ID { get; set; }
        public string Title { get; set; }

        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string Genre { get; set; }
        public decimal Price { get; set; }
    }
}

Lớp Movie bao gồm:

  • Trường ID là khóa chính trong database.
  • [DataType(DataType.Date)]: Thuộc tính DataType bắt buộc là kiểu date. With this attribute:
    • Người dùng không bắt buộc phải nhập thông tin thời gian vào trường ngày.
    • Chỉ ngày được hiển thị, không phải thông tin thời gian.

Tạo page tự động theo lớp Movie trong model

Trong phần này, Movie Model được tạo ra. Nghĩa là, công tạo ra các trang cho các hoạt động Create, Read, Update và Delete (CRUD) cho Movie Model một cách tự động.

Tạo thư mục Pages/Movies:

Nhấp chuột phải vào thư mục  Pages > Add > New Folder.
Đặt tên cho thư mục là Movies
Nhấp chuột phải vào thư mục Pages/Movies > Add > New Scaffolded Item.

Trong hộp thoại Add Scaffold, chọn Razor Pages using Entity Framework (CRUD) > Add.

Hoàn thành hộp thoại Add Razor Pages using Entity Framework (CRUD)

Trong lớp Model hiển thị trong dropdow, chọn Movie (RazorPagesMovie.Models).
Trong Data context class, chọn dấu + (dấu cộng) và chấp nhận tên được tạo là RazorPagesMovie.Models.RazorPagesMovieContext.
Chọn Add.

Tệp appsinstall.json được cập nhật với chuỗi kết nối được sử dụng để kết nối với cơ sở dữ liệu cục bộ.

Quá trình scaffold tạo và cập nhật các tệp sau:

Files Được tạo

  • Pages/Movies: Create, Delete, Details, Edit, and Index.
  • Data/RazorPagesMovieContext.cs

File cập nhật

  • Startup.cs

Các tập tin được tạo và cập nhật được giải thích trong phần tiếp theo.

Initial migration

Trong phần này, Package Manager Console (PMC) được sử dụng để:

Thêm một di chuyển ban đầu.
Cập nhật cơ sở dữ liệu với việc di chuyển ban đầu.
Từ menu Tools, chọn NuGet Package Manager > Package Manager Console.

Trong PMC, nhập các lệnh sau:

Add-Migration Initial
Update-Database

Các lệnh trước tạo cảnh báo sau: “Không có loại nào được chỉ định cho cột thập phân ‘Price’ trên loại thực thể ‘Price’. Điều này sẽ khiến các giá trị bị cắt âm thầm nếu chúng không phù hợp với độ chính xác và tỷ lệ mặc định. Kiểu cột máy chủ SQL có thể chứa tất cả các giá trị bằng cách sử dụng ‘HasColumnType ()’. ”

Bạn có thể bỏ qua cảnh báo đó, nó sẽ được sửa trong hướng dẫn sau.

thêm lệnh trong cmd: ef migrations add InitialCreate tạo mã để tạo schema cơ sở dữ liệu ban đầu. Schema dựa trên mô hình được chỉ định trong DbContext (Trong tệp RazorPagesMovieContext.cs). InitialCreate được sử dụng để đặt tên cho các lần Up/Down phiên bản migration. Bất kỳ tên nào cũng có thể được sử dụng, nhưng theo quy ước, một tên được chọn mô tả việc Up/Down tác động như thế nào vào database.

Lệnh cmd: ef database update sẽ Up việc chỉnh sửa databse vào database và cũng thêm code chỉnh sửa vào trong tệp Migrations/<time-stamp>_InitialCreate.cs.

Kiểm tra bối cảnh đăng ký với dependency injection.
ASP.NET Core được xây dựng với dependency injection. Các dịch vụ (như EF Core DB context) được đăng ký với dependency injection trong quá trình khởi động ứng dụng. Các thành phần yêu cầu các dịch vụ này (như Razor Pages) được cung cấp các dịch vụ này thông qua các tham số của hàm tạo. Mã constructor nhận được một cá thể DB context sẽ được hiển thị sau trong hướng dẫn.

Công cụ  scaffold tự động tạo DB context và đăng ký nó với  dependency injection container.

Kiểm tra phương thức Startup.ConfigureService. Các dòng được tô đậm đã được thêm vào bởi scaffold :

// This method gets called by the runtime. 
// Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        // This lambda determines whether user consent for non-essential cookies is 
        // needed for a given request.
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

    services.AddDbContext<RazorPagesMovieContext>(options =>
      options.UseSqlServer(
          Configuration.GetConnectionString("RazorPagesMovieContext")));
}
RazorPagesMovieContext phối hợp chức năng EF Core (Create, Read, Update, Delete, v.v.) cho Movie model. Data context (RazorPagesMovieContext) có nguồn gốc từ Microsoft.EntityFrameworkCore.DbContext. Data context xác định các thực thể được bao gồm trong mô hình dữ liệu.
using Microsoft.EntityFrameworkCore;

namespace RazorPagesMovie.Models
{
    public class RazorPagesMovieContext : DbContext
    {
        public RazorPagesMovieContext (DbContextOptions<RazorPagesMovieContext> options)
            : base(options)
        {
        }

        public DbSet<RazorPagesMovie.Models.Movie> Movie { get; set; }
    }
}

Mã trước tạo một thuộc tính Dbset <Movie> cho tập thực thể. Trong thuật ngữ Entity Framework, một tập thực thể thường tương ứng với bảng cơ sở dữ liệu. Một thực thể tương ứng với một hàng trong bảng.

Tên của chuỗi kết nối được truyền vào ngữ cảnh bằng cách gọi một phương thức trên đối tượng DbContextOptions. Để phát triển cục bộ,  ASP.NET Core configuration system đọc chuỗi kết nối từ tệp appsinstall.json.

Lệnh Add-Migration tạo code để tạo database schema ban đầu. Lược đồ này dựa trên model được chỉ định trong tệp RazorPagesMovieContext (Trong tệp Data / RazorPagesMovieContext.cs). Đối số ban đầu được sử dụng để đặt tên cho các di chuyển. Bất kỳ tên nào cũng có thể được sử dụng, nhưng theo quy ước, một tên mô tả việc di chuyển được sử dụng.

Lệnh Update-Database chạy phương thức Up trong tệp Migrations/{time-stamp}_InitialCreate.cs, tạo cơ sở dữ liệu.

Test app

  • Chạy ứng dụng và nối /Movies vào URL trong trình duyệt (http: // localhost: port / movies).

Nếu bạn gặp lỗi:

SqlException: Cannot open database “RazorPagesMovieContext-GUID” requested by the login. The login failed. Login failed for user ‘User-name’.

Bạn đã bỏ lỡ bước migration nào đó.

Kiểm tra trang Create.

 

Bài 15: Sao Phá Quân

PHÁ QUÂN

Phá quân thuộc dương Thủy, là sao thứ 7 trong chòm Bắc đầu. Tính chất “chiến tướng” tương tự như Thất sát nhưng khác là ở chỗ: Thất sát là tướng mà Phá quân là tiên phong, do vậy Phá quân hóa khí là Hao.

Bởi Phá quân “năng công bất năng thủ”– hợp với thế tiến công hơn phòng thủ, nên Phá quân tọa mệnh so với Thất sát có tính “động” nhiều hơi. Dù cho hội được tử vi thì cũng không thể vì thế mà “hóa phá vi quyền”– Tử vi dụng Phá quân thành quyền tinh được, ngược lại tính động của Phá quân còn làm ảnh hưởng đến tính ổn định của Tử vi.

Phá quân gặp sát tinh mà không có cát tinh phù trợ, có thể bị hình thương trên thân thể.

Phá quân tốt nhất bản thân Hóa lộc, tốt nhì là hội được Lộc. Khi đó sẽ cải thiện bản tính động. Với Hóa quyền cũng có thể tương tự như trên nhưng không tốt bằng Hóa lộc.

Nếu được phụ tá tinh và cát tinh hội chiếu, tránh được sát tinh thì là tổ hợp tốt nhất cho Phá quân, khi đó Phá Quân có thể vừa “công”, vừa “thủ”, gặp vận đích thực là chiến tướng, cách cục này không phải nhỏ.

Phá Quân cũng là chiến tướng, nhưng so với Thất Sát thì kém một bậc, sở dĩ Thất Sát có thể thụ mệnh Hoàng Đế một cách đường đường chính chính, nhưng Phá Quân mà trực tiếp thụ mệnh Hoàng Đế liền có điểm không hợp, vì thế tổ hợp Tử Vi Phá Quân tốt đẹp khi tính chất ổn định của Tử Vi được duy trì.

Không có Lộc thì Phá quân như chiến tướng bị hao tổn, không có hậu phương, chung cuộc cũng bại hoặc bị hạ thấp. Chính thế nên muốn phòng trừ cái việc “chiến tướng bị hao tổn” thì quan trọng phải tậm trung tâm lực vào chỉ một việc. Phá Quân thủ mệnh không thể là người nhàn nhã, lắm ý niệm.

Lời bàn: Về Phá Quân thì cũng có nhiều quan điểm trái chiều nhau. Ở đây, có lẽ Vương tiên sinh quá coi trọng hình ảnh “chiến tướng” khi đem so sáng với Thất sát, nhưng có lẽ về bản chất thì Phá Quân khổng hẳn thê. Sở dĩ Tử vi không làm cho Phá hóa Quyền được là chính vì cái tính phản nghịch của nó. Khác với Thất Sát chỉ là “thừa hành chính lệnh”. Trong quan điểm của Vương tiên sinh thì cho rằng Phá Quân cần hội nhiều cát tinh mới quý, tuy nhiên cần phải xem xét trong trường hợp Văn tinh, vì Phú nói “Phá quân hội văn tinh nhất sinh bần sĩ”. Phá quân vốn là “nghi loạn bất nghi trị” hợp với thời loạn hơn là lúc yên ổn, có lẽ vì thế mà một số quan điểm cho rằng phải được sát tinh đắc cách phò trợ mới tốt, như Phá đắc Không Kiếp vậy. Tuy nhiên, theo quan điểm của một số nghiên cức thì thấy rằng, Phá đắc sát tinh, tuy có thể phấn phát nhất thời nhưng chắc chắn sẽ phải trả giá, cũng không phải là điều tốt. Như thế, có nghĩa là Phá thể hiện tính cô độc cực cao, chẳng hợp với nhóm nào. Cũng nên chiêm nghiệm.

Bài 14: Sao Thất Sát

THẤT SÁT

Thuộc âm kim, là ngôi thứ 5 của chòm Nam đẩu, là chiến tướng trên trời.Là kẻ xung phong hãm trận, giết giặc trên chiến trường, vì thế Thất sát mang theo tính chất cương khắc.

Thất sát không nên gặp Hình Kỵ vì sợ rằng quá cô khắc, nếu mà lại hội thêm sát tinh nữa, thì đời người càng thêm gian khổ.

Chế được cái tính cương khắc của Thất Sát, chỉ có Lộc tinh ở Tỵ (1), hội Hóa Lộc hay Lộc tồn đều tốt, có thể làm cho cái tính cương khắc của Thất sát hóa thành chuyên nghiệp, hoặc công nghệ, trong cái sự phân công rất tinh tế của xã hội hiện đại, người chuyên nghiệp cũng tương đương với khái niệm giầu có.

Ngoại trừ Lộc tinh ra, để chế hóa cái tính ác của Thất sát là Tử vi, gọi là “hóa sát vi quyền” (biết SÁT thành QUYỀN). Khi Thất sát và Tử vi cùng gặp nhau hoặc đối cung với nhau mà được quần thần cùng hội vào, lại tránh được sát tinh phá phách thì mới là hợp cách. Giống như Đại tướng nhận lệnh của Để tọa, khí khái phi phàm, nếu lại hội thêm được Lộc tinh thì phú quý khỏi phải bàn. Nếu có sát tinh trùng phá, thì khả năng là sẽ trở thành mệnh của một nhà công nghiệp.

Thất sát là tướng quân, trực tiếp nhận mệnh của hoàng đế xuất ngoại đánh trận, nhưng phía sau có quân quyền, hoàn toàn phụ thuộc vào chuyện quân lương mà thành sự, vì thế mà Thất sát rất cần gặp Lộc (rất tốt nếu gặp cả song Lộc). Mà Thất sát vốn là đại tướng nên ưa độc đoán độc hành, vì thế mà Tả Hữu Xương Khúc đối với Thất Sát cũng không quan trọng lắm. Cũng giống như Vũ Khúc, Khôi Việt tương đối quan trọng đối với Thất sát.

Thất sát cũng giống như Tham Lang, đều là chủ BIẾN, nhưng phúc độ của Sát lớn hơn Tham Lang vậy.

(1) Câu này hơi tối nghĩa, nguyên văn viết là “ Hóa Thất Sát đích cương khắc, duy Lộc tinh tỵ” – Chữ TỴ trong văn bản này là Chi Tỵ trong 12 địa chi, nhưng như thế không có nghĩa, ngờ rằng là nhầm với chứ TỴ nghĩa là TRÁNH ĐƯỢC.

Lời bàn: Đối với Thất Sát, điểm quan trọng là cái tính CƯƠNG KHẮC, Vương tiên sinh đã phân tích rằng “không nên gặp Hình Kỵ vì sợ quá cô khắc, nếu gặp thêm sát tinh thì đời người là càng thêm gian khổ”, lý luận của Vương tiên sinh rất sắc bén, cổ nhân đã có câu “Thất Sát – Thiên Hình, cương táo nhi cô”, trở nên cứng rắn, khô khan mà lại cô độc. Đương nhiên là cuộc đời sẽ vì thế mà kinh lịch gian tân. Tuy nhiên, cái sự lập luận ấy cần phải dựa trên tính lý của Sát mà luận, chứ chỉ căn cứ vào cái chuyện ví von Sát là chiến tướng mà phân tích, thì e rằng sẽ rơi vào chuyện suy diễn thường tình. Và cũng cần phải xem xét thêm luận điểm cho rằng Lộc tinh có thể giải trừ được cái tính cương khắc của Sát, điều này chưa hẳn đúng lắm, bởi Lộc tinh tuy có thể biến cái sự sát phạt của Thất sát thành tài phú, nhưng cái tính cương cường thì khó lòng vì thế mà mất đi được. Có thể trong xã hội hiện đại tiền bạc có thể đánh bóng con người, nhưng cái tính cương khắc của tinh diệu thì khó lòng cải biến được, cũng là điều cần suy ngẫm.

Bài 13: Sao Thiên Lương

THIÊN LƯƠNG

Thuộc Dương Thổ, là ngôi thứ 3 trong chòm Nam đẩu, hóa khí là ẤM TINH, nhưng cũng lại hóa vì HÌNH TINH. Nguyên nhân Thiên Lương hóa khí là Hình tinh là do nó lại có tính chất “cương khắc cô kỵ”, nếu như lúc này mà lại gặp Thiên Hình cung Kình Dương thì tình cương khắc sẽ mạnh lên, cho nên cách này là không tốt.

Nhưng Thiên Lương cũng có tính chất của cái bóng che chở, tức là ẤM (hán việt: Ấm tức là cái bóng che chở của cha mẹ, bề trên, bởi Lương là biểu trưng của Phụ Mẫu). Ấm (tính chất) tức là tiêu tai đặc trưng lớn nhất là “tiên phá hậu lập” (trước phá đi rồi sau mới lập thành), trước đắng mà sau mới có vị ngọt. Nhưng mà trước phải có tai vạ thì sau mới phát huy được tính chất của Thiên Lương. Tuy nhiên, cuối cùng thì cái Hung cũng sẽ tiêu tán hết, nhưng độ biến hóa họa phúc của đời người quá lớn, cũng không phải là điều tốt.

Thiên Lương rất tốt nếu gặp Hóa Lộc, nhưng cũng tốt nếu là Hóa Khoa, lúc ấy sẽ cái mặt tốt đẹp lương thiện của Thiên Lương sẽ biểu hiện mạnh mẽ nhất. Nếu được Phụ Bật Xương Khúc cùng hội hợp thì lại càng có khả năng phát huy cái tình chất “ẤM” của Thiên Lương, càng về sau càng mạnh. Thiên Lương có khả năng tiêu tai giải khó, sở dĩ Thiên Lương cũng hay làm nên cái sự “tiêu tai” là bởi Thiên Lương chủ quý, nên có thể hóa khí thành khoa tinh.

Trong cách cục Thiên Lương – Hình Kỵ: Cái ánh sáng màu sắc của Thiên Lương Hình Kỵ thì ít, mà cái sự âm u của Thiên Lương Hình KỴ thì nhiều. Tại sao lại chiếu sáng?

Đại khái là nếu được Thái Dương miếu vượng chiếu rọi thì tỏa sáng, hoặc đắc khoa quyền hội lợp mà tỏa sáng (đương nhiên nếu lại được thêm Thái dương miếu vượng hòa cùng Khoa Quyền chiếu sáng nữa thì cực tốt). Thứ nhì là nếu gặp được Thái Âm thì cũng tốt nhưng trường hợp này Thiên Lương trở nên thâm trầm, nội liễm (thâu nhận vào bên trong). Nếu như những điều ở trên hoàn toàn không có, Thiên Lương trở nên lén lén lút lút, soi mói bắt bẻ, không hợp với người khác. Lúc này sẽ phát huy đầy đủ cái tính Hình của Thiên Lương.

Lời bàn: Dịch đến đây, mới thấy được Vương tiên sinh giải thích vì sao Thiên Lương lại hóa khí là Hình Tinh. Cũng là một ý kiến mới, khi ông cho rằng Thiên Lương có thêm tính chất Cương-Khắc-Cô-Kỵ. Nhưng trên thực tế, và theo các tài liệu, quan điểm khác thì dường như tính chất này không rõ ràng lắm, có phần mờ nhạt. Nhưng ở đây, Vương tiên sinh rất coi trọng cái cách Thiên Lương gặp Hình Kỵ, có lẽ đây là quan điểm riêng của ông, cũng là một điều cần chiêm nghiệm. Tất nhiên, là tính chất của Thiên Lương cũng như bất kể một sao nào, đều phụ thuộc vào cái sự miếu hãm của nó, chứ không hẳn chỉ có đắc cách như Vương tiên sinh nhận xét. Cái điều Vương tiên sinh luận rằng “tiên phá hậu lập” rất xuất sắc, bởi vì Lương là Ấm tinh, vốn là thừa hưởng của tiền nhân để lại, ở đời mấy ai giữ được, nếu không phải là nội lực tự cường. Việc Lương gây nên sự biến đổi họa phúc lớn của đời người, chưa hắn chỉ có thế, có lẽ cần xem xét thêm các điều kiện khác nữa chăng.

Bài 12: Sao Thiên Tướng

THIÊN TƯỚNG

Thuộc dương thủy, là ngôi thứ hai trong chòm Nam đẩu, hóa khí lá Ấn tinh, được ví như cái ấn đeo của Hoàng Đế, cho nên nếu ở trong tay Hoàng đế anh minh thì là cứu tinh của nê dân, mà trong tay Hôn quân bạo chúa thì tàn hại bách tính – giúp cho phường hung bạo. Bởi vậy, bản chất của Thiên tướng là gặp Cát thì Thiện, gặp Hung thì Ác. Thiên tướng hoàn toàn chịu hoàn cảnh của bên ngoài mà biến hóa, khi luận đoán phải hết sức cẩn thận.

Trong Tứ Sát, Thiên tướng sợ nhất Hỏa Linh, cho nên có thuyết nói rằng “Thiên tướng Hỏa linh trùng Phá, tàn chướng” – (Thiên tướng Hỏa linh mà gặp Phá, tàn tật), có khả năng có cố tật, hoặc thân thể yếu đuối nhiều bệnh tật.

Đoán sự cát hung của Thiên tướng tất phải xem xét Lân cung (hai cung bên cạnh bản cung), như Cự Môn Hóa Kỵ giáp bên sẽ thành cách “Hình Kỵ giáp Ấn” (do Thiên Lương là Hình) – không tốt. Như Cự Môn Hóa Lộc, là cách “Tài Ấm giáp Tướng” (Thiên Lương là Ấm), là một kết cấu đẹp của Thiên Tướng. Đương nhiên vẫn chủ yếu là xem sự phân bố của Lục Cát, Lục sát mà đoán định.

Một đặc trưng lớn nhất của Thiên Tướng là “không có tính cách” (đây là một thuật ngữ dùng trong luận đoán, không có nghĩa là người có Thiên tướng thủ mệnh không có tính cách).

Cho nên trong mưới bốn chính tinh chỉ có Thiên tướng là rất coi trọng Lân cung, bị ảnh hưởng rất mạnh từ hai cung bên cạnh bất luận là Hình Kỵ giáp, Tài Ấm giáp, hay Dương Đà giáp.

Giáp Hỏa Linh, giáp Khoa Quyền, cũng như giáp Khôi Việt … đều có ảnh hưởng mạnh đến Thiên Tướng. Tại lá số mà Thiên tướng gặp cách giáp cung, đôi khi lại biểu hiện tính cách không thể làm chủ bản thân, như vẫn nói là “hình thể giống người mạnh” (thành ngữ – ý nói về cái hình thì trông giống người mạnh, mà không phải là mạnh).

Thiên Tướng cũng có tính chất tương tự như Thiên Cơ. Đều dựa phần nhiều vào phụ tá.

Lời bàn: đoạn luận về Thiên tướng này của Vương tiên sinh chưa thật sắc xảo lắm. Có lẽ Vương tiên sinh quá coi trọng cái sự ảnh hưởng của Lân cung đến Thiên Tướng. Gần như các quan điểm của Vương tiên sinh đều trái ngược với những nhận xét của cổ nhân về Thiên tướng. Theo “đẩu số toàn thư” thì bản chất của Thiên Tướng vốn là Ấn tinh (ấn là con dấu, con triện), biểu thị cho uy quyền, tài lộc hơn thế nữa với nhận xét về tính tình của Thiên Tướng “kiến nhân nan hữu trắc ẩn chi tâm, kiến nhân ác hữu bất bình chi khí” (gặp người khó thì động lòng trắc ẩn, gặp kẻ ác thì nổi sự bất bình), thì càng không thể nhận xét rằng “thiên tướng là sao không có tính cách”. Tính cách “gặp thiện theo thiện, gặp ác theo ác” của Thiên tướng không thể hiện rõ ràng lắm. Với các nhận xét về cách cục của Thiên tướng như ở trên chưa được thuyết phục lắm, ví như cách Hình Kỵ giáp Ấn mà bảo rằng Thiên Lương là Hình thì thật là chưa chính xác vậy, hơn thế nữa, bản chất của Hình Kỵ khi giáp Ấn không phải do Ấn tinh tạo nên, mà bất cứ sao nào khi gặp các cách GIÁP như Giáp hình kỵ, Giáp Dương Đà, Giáp Không Kiếp cũng đều xấu vậy, không hẳn chỉ có Thiên tướng. Dịch đoạn này cảm thấy nghi ngờ, không chắc có phải là quan điểm của Vương tiên sinh hay chỉ là do người sau thêm thắt vào? Người đọc cũng cần tham khảo và chắt lọc thêm vậy. Ngoài ra, một đặc tính về Tài của Thiên tướng chưa thấy được nhắc đến, vì Tướng và Phủ luôn trong tam hợp cho nên mới có câu “Phủ Tướng triều viên, nãi vi y lộc chi thần”, là thần của y lộc. Có lẽ đây cũng là một thiếu sót chăng?

Bài 11: Sao Cự Môn

CỰ MÔN

Thuộc Âm Thổ, khí thuộc Âm Kim, là sao thứ hai trong chòm Bắc Đẩu.

Trong đẩu số, Cự môn là ám tinh, nhất định phải có Thái Dương miếu vượng hội chiếu, hoặc Lộc Quyền hội hợp mới có thể giải được tính ám của Cự Môn. Nếu không có Thái Dương hội chiếu hoặc Lộc Quyền cứu giải, Cự Môn sẽ đem lại thị phi, nghi kỵ.

Cự môn còn được ví như tài ăn nói, nếu cát thì nói hay, giỏi biện, nếu hung thì ăn nói giảo hoạt. Nếu hội Thái Dương hãm, Hình Kỵ thì dễ rước cái họa khẩu thiệt, thậm chí kiện cáo. Năng lực đối kháng sát tinh của Cự môn rất yếu, cho nên tuyệt không nên gặp sát tinh, rất cần cát tinh cùng với Hóa Lộc, Hóa Quyền, cải hóa được Cự Môn, không chỉ ăn nói tuyệt vời mà thậm chí còn có thể trở thành nghề nghiệp, có thể làm luật sư, diễn thuyết gia, thuộc hàng có đẳng cấp, lại có khả năng truyền bá, tiếp thị tài ba. Nếu được cách cục thích hợp phối hợp thì phú quý không thiếu.

Cự môn còn biểu trưng của chướng ngại lớn, che lấp tất cả mọi thứ. Trong đời người có thể có một giai đoạn gian khổ đối với lịch trình, hoặc một giai đoạn thương tâm đối với chuyện cũ. Hoặc biểu trưng cho người thích nói, dùng ngôn từ che giấu người khác, biểu hiện là người thao thao bất tuyệt, thích tranh luận. Nếu như cách cục tốt (Như đắc Hóa Quyền lại gặp Xương Khúc), có học thức lại có sức biểu đạt tốt, như vậy đương nhiên tuyệt không phải là phường nói hão.Kỳ thực, tại hiện đại, Cự môn được đánh giá cao hơn so với cổ đại nhiều lắm, bởi vì hiện thời là cần phải bao quát, tiếp thị xã hội. Từ việc cạnh tranh tổng thống của nước Mỹ đến một nhân viên tiếp thị, đều cần đến việc ăn nói linh hoạt (bất kể là nói thật hay không thật). Tóm lại là những người ăn nói rất tốt, tuyệt không thể thiếu Cự môn.

Lời bàn: Vương tiên sinh đánh giá rất cao khả năng ăn nói của Cự Môn vì nó hợp với xã hội hiện đại, tuy nhiên cần phải nhớ rằng chỉ thực sự tốt khi Cự Môn đắc cách hội Quyền Lộc, Xương Khúc. Đoạn Vương tiên sinh luận rằng “Trong đời người có thể có một giai đoạn gian khổ đối với lịch trình, hoặc một giai đoạn thương tâm đối với chuyện cũ” thật là sắc bén. Duy chỉ có điều, chưa thấy Vương tiên sinh phân tích về tính Tài khí của Cự Môn.

Bài 10: Sao Tham Lang

THAM LANG

Tham lang thuộc Dương Mộc, khí thuộc thủy, ví như Tình Dục và Vật Dục, còn gọi là Chính Đào Hoa, nếu được chế hóa thì vẫn có thể tốt. Nếu được chế hóa, tình dục vật dục đặt được cân bằng, mà lại được cát tinh hội hợp thì là cao cách vậy. Nếu không được chế hóa mà lại gặp sát tinh hội hợp, không cần biết là thiên về tình dục hay vật dục, nhưng đều có khuyết điểm.

Hóa Lộc gia tăng vật dục còn Hóa kỵ thì giảm bớt dục vọng. Tử Tham mà được Tả Hữu Xương Khúc là được chế hóa, Vũ Tham mà được Hỏa Linh là được chế hóa, nếu lại hội được Cát Tinh, Cát Hóa, có thể làm đại tướng, uy chấn biên cương.Liêm Tham ngộ Không, Thiên hình, Hóa kỵ là được chế hóa, có khả năng tình dục mạnh, thơ rượu phong lưu mà biến thành văn nghệ, nghệ thuật.Nếu không được chế hóa mà lại gặp Kình Dương, Đà La thì vì sắc mà rước họa.

Tham lang cũng là chủ biến, nhưng cái biến của nó là “đổi thang mà không đổi thuốc” (chỉ thay đổi cái vỏ bề ngoài mà bản chất thì không đổi), mượn màu son phấn để che giấu toan tính.Tham Lang cũng là một tay giao tiếp đối đáp thiện nghệ, nhưng cái ứng đối của nó phần nhiều là ở tửu sắc phong lưu. Cũng đôi khi thích các sự vật thần bí, thuộc loại quỷ quỷ quái quái, nhưng cái sở thích của nó là loại đông tây thần bí, mà tịnh không phải là nghiên cứu chuyên sâu.Cũng dựa trên tính chất tương đối của Tham Lang, nếu gặp được Xương Khúc, ngộ Không, cũng với Thiên Hình có thể phát huy tiềm năng nghệ thuật của Tham Lang.

Lời bàn: Vương tiên sinh có đưa ra quan điểm về các cách chế hóa đối với sao Tham Lang trong từng trường hợp. Tuy nhiên dường như Vương tiên sinh không coi trọng các tính chất về tài khí của Tham Lang, ngay cả khi gặp Hỏa linh, điều này có khác so với các quan điểm xưa nay. Có một điều mới ở đây là Vương tiên sinh cho rằng Thiên Hình có thể chế giải được tính dâm của Tham Lang, cũng cần phải xem xét.

thai-van-hoat