Tạo một mô hình dữ liệu Entity Framework cho ứng dụng ASP.NET MVC


Ứng dụng web của trường đại học Contoso biểu diễn cách tạo ra một ứng dụng ASP.NET MVC dùng Entity Framework. Ứng dụng mẫu là website của trường đại học Contoso (trường đại học này chỉ là hư cấu – không có thật). Nó bao gồm các chức năng như đăng ký nhập học, tạo khóa học, và phân lớp cho giảng viên. Loại bài này sẽ hướng dẫn các bước để xây dựng nên ứng dụng Contoso University. Bạn có thể tải về ứng dụng hoàn chỉnh hoặc tạo mới bằng cách theo các bước hướng dẫn trong bài. Các ví dụ được trình bày bằng C#, mã ứng dụng để có thể tải về được viết bằng C# và VB. Nếu có câu hỏi nào không liên quan trực tiếp đến loại bài này, bạn có thể gửi lên ASP.NET Entity Framework forum hay Entity Framework and LINQ to Entities forum. Chúng tôi sẽ coi như bạn đã biết cách làm việc với ASP.NET MVC trong Visual Studio, nếu chưa, bạn có thể tham khảo basic ASP.NET MVC Tutorial. Nếu bạn định dùng WebForm, xem loại bài Getting Started with the Entity FrameworkContinuing with the Entity Framework. Trước khi bắt đầu, hãy kiểm tra và đảm bảo rằng các thành phần sau đã được cài đặt:

Ứng dụng Web Contoso University

Ứng dụng bạn xây dựng sau khi hoàn thành loại bài này sẽ là một website trường đại học đơn giản.

Contoso_University_home_page

Người dùng có thể xem và cập nhật thông tin sinh viên, môn học và giản viên. Một vài màn hình bạn sẽ tạo được hiển thị dưới đây:

Students_Index_page

Students_Create_page

Instructors_index_page

Định dạng hiển thị được giữ giống với cái được tạo tự động bởi mẫu có trong Visual Studio, do vậy loại bài này sẽ chủ yếu tập trung vào cách sử dụng Entity Framework.

Các cách tiếp cận trong lập trình với Entity Framework

Như bạn thấy trong hình vẽ sau, có ba cách bạn có thể làm việc với dữ liệu trong Entity Framework: Database First, Model First, và Code First.


Development_approaches_diagram

Database First

Nếu đã có sẵn một cơ sở dữ liệu (CSDL), Entity Framework có thể tự động tạo ra một mô hình dữ liệu bao gồm các lớp và thuộc tính tương ứng với các đối tượng CSDL như bảng và cột. Thông tin về cấu trúc CSDL của bạn(store schema), mô hình dữ liệu (conceptual model), và việc ánh xạ giữa chúng được lưu dưới dạng XML trong file .edmx. Visual Studio cung cấp một trình thiết kế Entity Framework, là một trình thiết kế dạng đồ họa cho phép bạn dùng để hiển thị và chỉnh sửa file .edmx. Các bài Getting Started With the Entity FrameworkContinuing With the Entity Framework trong loạt bài “Sử dụng Entity Framework với Web Forms” dùng Database First.

Model First

Nếu hiện bạn chưa có sẵn một CSDL, bạn có thể bắt đầu bằng cách tạo một mô hình dùng trình thiết kế Entity Framework trong Visual Studio. Sau khi hoàn thành, trình thiết kế này có thể tạo ra các câu lện DDL(data definition language) để tạo nên CSDL. Cách tiếp cận này cũng dùng file .edmx để lưu thông tin mô hình và ánh xạ (mapping). Loạt bài What’s New in the Entity Framework 4 có một ví dụ về việc dùng cách phát triển Model First.

Code First

Không phụ thuộc vào việc đã có CSDL hay chưa, bạn có thể viết các lớp của riêng bạn và các thuộc tính tương ứng với các bảng và các cột, sau đó dùng chúng với Entity Framework mà không cần tới file .edmx. Đó lý vì sao đôi khi bạn thấy cách tiếp cận này được gọi là Code Only. mặc dù tên chính thức của nó là Code First. Việc ánh xạ giữa cấu trúc lưu trữ và mô hình khái niệm biểu diễn trong code của bạn được quản lý với những quy ước và tập API đặc biệt cho trước. Nếu bạn chưa có một CSDL, Entity Frame có thể tạo ra cho bạn, và thậm chí xóa và tạo lại nếu cấu trúc bị thay đổi. Loạt bài này sẽ dùng cách phát triển Code First.

Tập API cho việc truy cập dữ liệu trong Code First được dựa trên lớp DbClass. Tập API này cũng được dùng với Database First và Model First. Để có thông tin xem thêm bài When is Code First not code first? trên blog của nhóm Entity Framework.

POCO (Plain Old CLR Objects)

Mặc nhiên, khi dùng cách tiếp cận Database First hay Model First, các lớp thực thể trong mô hình dữ liệu sẽ thừa kế từ lớp EntityObject, lớp này sẽ cung cấp các chức năng Enity Framework. Điều này có nghĩa là các lớp đó về mặt kỹ thuật không persistence ignorant, và do vậy chúng không đáp ứng đầy đủ các yêu cầu của thiết kế domain-driven (nôm na là các lớp này thừa kế từ các lớp khác nên không tập trung duy nhất vào việc giải quyết yêu cầu bài toán). Các cách tiếp cận của EF cũng có thể làm việc được với POCO (plain old CLR objects), tức đáp ứng được persistence-ignorant bởi vì chúng không thừa kế từ lớp EntityObject. Trong loạt bài này chúng ta sẽ dùng các lớp POCO.

Tạo một ứng dụng Web MVC

Trước khi bắt đầu, hãy chắc chắn là các phần mềm sau đã được cài đặt lên máy tính của bạn:

Mở Visual Studio và tạo một project có tên “ContosoUniversity” dùng ASP.NET MVC 3 Web Application:

New_project_dialog_box

Trong hộp thoại New ASP.NET MVC 3 Project chọn Internet ApplicationRazor view engine, xóa ô Create a unit test project, rồi nhấn OK.

Project_template_options

Thiết đặt site style

Một số thay đổi nhỏ để thiết đặt menu, layout và trang chủ.

Để thiết đặt menu Contoso University, trong file Views\Shared\_Layout.cshtml, thay thế nội dung bên trong đoạn tiêu đề h1 và các liên kết trong menu, giống như ví dụ dưới đây:

<!DOCTYPE html>
<html>
<head>
    <title>@ViewBag.Title</title>
    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
    <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
</head>
<body>
    <div class="page">
       <div id="header">
            <div id="title">
                <h1>Contoso University</h1>
            </div>

            <div id="logindisplay">
                @Html.Partial("_LogOnPartial")
            </div>
            <div id="menucontainer">
                <ul id="menu">
                    <li>@Html.ActionLink("Home", "Index", "Home")</li>
                    <li>@Html.ActionLink("About", "About", "Home")</li>
                    <li>@Html.ActionLink("Students", "Index", "Student")</li>
                    <li>@Html.ActionLink("Courses", "Index", "Course")</li>
                    <li>@Html.ActionLink("Instructors", "Index", "Instructor")</li>
                    <li>@Html.ActionLink("Departments", "Index", "Department")</li>
                </ul>
            </div>
        </div>
        <div id="main">
            @RenderBody()
        </div>
        <div id="footer">
        </div>
    </div>
</body>
</html>

Trong file Views\Home\Index.cshtml, xóa tất cả mọi thứ dưới phần tiêu đề h2.

Trong file Controllers\HomeController.cs, thay thế “Welcome to ASP.NET MVC!” với “Welcome to Contoso University!”

Trong file Content\Site.css, thay đổi như sau để chuyển các tab trên menu sang trái:

  • Trong định nghĩa cho main #main, thêm clear: both;, giống như ví dụ dưới đây:
     #main
     {
         clear: both;
         padding: 30px 30px 15px 30px;
         background-color: #fff;
         border-radius: 4px 0 0 0;
         -webkit-border-radius: 4px 0 0 0;
         -moz-border-radius: 4px 0 0 0;
     }
  • Trong định nghĩa cho nav#menucontainer, thêm clear: both; float: left;,như ví dụ dưới đây:nav,
    #menucontainer {
        margin-top: 40px;
        clear: both;
        float: left;
    }

Chạy thử. Bạn sẽ thấy trang chủ với menu chính.

Contoso_University_home_page

Tạo mô hình dữ liệu

Tiếp theo bạn tạo các lớp thực thể đầu tiên cho ứng dụng Contoso University. Bạn sẽ bắt đầu với ba thực thể sau:

Class_diagram

Có một mối quan hệ một nhiều giữa Student và Enrollment, và một quan hệ một nhiểu giữa Course và Enrollment. Nói cách khác, một sinh viên có thể tham gia nhiều khóa học, và một khóa học lại có thể có nhiều sinh viên tham gia.

Trong phần tiếp theo, bạn sẽ tạo một cho mỗi thực thể trên.

Ghi chú Nếu thử chạy project trước khi hoàn thành việc tạo tất cả các lớp thực thể, bạn sẽ bị lỗi dịch chương trình.

Thực thể Student

Student_entity

Trong thư mục Model, tạo một file Student.cs và thay thế nội dung với đoạn lệnh sau:

using System;
using System.Collections.Generic;

namespace ContosoUniversity.Models
{
    public class Student
    {
        public int StudentID { get; set; }
        public string LastName { get; set; }
        public string FirstMidName { get; set; }
        public DateTime EnrollmentDate { get; set; }
        public virtual ICollection<Enrollment> Enrollments { get; set; }
    }
}

Thuộc tính StudentID sẽ trở nên cột khóa chính của bảng tương ứng với lớp này trong CSDL. Mặc nhiên, EF diễn dịch một thuộc tính có tên ID hay TênlớpID như khóa chính.

Enrollment là một thuộc tính navigation. Các thuộc tính navigation giữ liên hệ với các thực thể có quan hệ với thực thể này. Trong trường hợp này, thuộc tính Enrollments của thực thể Student sẽ giữ tất cả các Enrollment có liên quan đến nó. Nói cách khác, nếu cho một dòng Student trong CSDL có liên kết với 2 dòng trong bảng Enrollment (các dòng chứa khóa chính của Student trong cột khóa ngoài StudentID), thuộc tính navigation Enrollments của thực thể Student sẽ chứa 2 đối tượng Enrollment đó.

Các thuộc tính navigation thường được định nghĩa là virtual, do vậy chúng có thể tận dụng được một tính năng của Entity Framework là lazy loading. (Lazy loading sẽ được giải thích sau, trong bài “Đọc các dữ liệu liên quan” cũng thuộc loại bài này). Nếu một thuộc tính navigation có thể chứa nhiều thực thể khác (như trong quan hệ nhiều-nhiều hay một-nhiều), kiểu của nó phải là ICollection.

Thực thể Enrollment

Enrollment_entity

Trong thư mục Models, tạo file Enrollment.cs và thay thế nội dung của nó với đoạn lệnh sau:


using System;
using System.Collections.Generic;

namespace ContosoUniversity.Models
{
    public class Enrollment
    {
        public int EnrollmentID { get; set; }
        public int CourseID { get; set; }
        public int StudentID { get; set; }
        public decimal? Grade { get; set; }
        public virtual Course Course { get; set; }
        public virtual Student Student { get; set; }
    }
}

Dấu chấm hỏi phía sau kiểu decimal chỉ ra Grade có thể mang giá trị null. Một Grade là null khác với việc nó bằng không – null nghĩa là Grade chưa được gán giá trị, trong khi zero nghĩa là nó đã được gán giá trị không.

Thuộc tính StudentID là một khóa ngoài, và thuộc tính navigation tương ứng là Student. Một Enrollment chỉ kết hợp với duy nhất một thực thể Student, do vậy thuộc tính này chỉ giữ một thực thể Student mà thôi (không giống như Student.Enrollments bạn thấy trước đây có giữ nhiều thực thể Enrollments).

Thuộc tính CourseID là khóa ngoài, và thuộc tính navigation tương ứng là Course. Một thực thể Enrollment kết hợp với một thực thể Student.

The Course Entity

Course_entity

Trong thư mục Models, tạo thêm Course.cs và thay thế nội dung với đoạn lệnh sau:

using System;
using System.Collections.Generic;

namespace ContosoUniversity.Models
{
    public class Course
    {
        public int CourseID { get; set; }
        public string Title { get; set; }
        public int Credits { get; set; }
        public virtual ICollection<Enrollment> Enrollments { get; set; }
    }
}

Enrollments là một thuộc tính navigation. Một thực thể Course có thể quan hệ với số lượng Enrollment bất kỳ.

Tạo một Database Context

Lớp chịu trách nhiệm chính trong việc kết hợp các tính năng của Entity Framework với một mô hình dữ liệu được gọi là lớp Database Context. Bạn tạo lớp này bằng cách thừa kế từ System.Data.Entity.DbContext. Trong chương trình bạn sẽ chỉ ra thực thể nào sẽ được bao gồm trong mô hình dữ liệu. Bạn cũng có thể tùy biến lại một số tính năng của Entity Framework. Trong project này, tên lớp sẽ là SchoolContext.

Tạo một thư mục tên DAL, trong thư mục đó bạn tạo một lớp có tên SchoolContext và thay thế nội dung của nó với đoạn lệnh sau:

using System;
using System.Collections.Generic;
using System.Data.Entity;
using ContosoUniversity.Models;
using System.Data.Entity.ModelConfiguration.Conventions;

namespace ContosoUniversity.Models
{
    public class SchoolContext : DbContext
    {
        public DbSet<Student> Students { get; set; }
        public DbSet<Enrollment> Enrollments { get; set; }
        public DbSet<Course> Courses { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        }
    }
}

Đoạn chương trình trên tạo một thuộc tính DbSet cho mỗi tập thực thể. Theo cách nói của Entity Framework, một tập thực thể đại diện cho một bảng trong CSDL và một thực thể tương ứng với một dòng trong bảng.

Câu lệnh trong phương thức OnModelCreating để tránh biến tên bảng thành dạng số nhiều. Nếu không làm vậy, tên các bảng được tạo có thể trở thành Students, Courses và Enrollments. Thay vì vậy, tên bảng sẽ là Student, Course và Enrollment. Các nhà phát triển thường không thống nhất với nhau về việc tên bảng có nên ở dạng số nhiều hay không. Trong loạt bài này, chúng ta sẽ dùng tên bảng dạng đơn, nhưng điều quan trọng là có thể lựa chọn dang tên bảng bạn muốn bằng cách thêm hoặc bỏ dòng lệnh trên.

(Lớp này nằm trong namespace Models, bởi vì trong một số trường hợp Code First cho rằng các lớp thực thể và lớp context trong cùng namespace).

Thiết đặt chuỗi kết nối

Bạn không phải tạo chuỗi kết nối, và trong trường hợp đó, Entity Framework sẽ tự động tạo một CSDL SQL Serrver Express. Tuy nhiên trong loạt bài này, bạn sẽ làm việc với CSDL SQL Server Compact, vì vậy bạn cần tạo một chuỗi kết nối để chỉ ra điều đó.

Mở file Web.config và thêm một chuỗi kết nối mới và tập ConnectionStrings, giống như trong ví dụ dưới đây. (Chú ý là cập nhật lại Web.config trong thư mục gốc của project, trong thư mục Views cũng có một file Web.config nhưng không cần cập nhật lại).

<add name="SchoolContext" connectionString="Data Source=|DataDirectory|School.sdf" providerName="System.Data.SqlServerCe.4.0"/>

By default, the Entity Framework looks for a connection string named the same as the object context class. The connection string you’ve added specifies a SQL Server Compact database named School.sdf located in the App_Data folder.

Mặc nhiên, Entity Framework tìm chuỗi kết nối có tên trùng với tên lớp context. Chuỗi kết nối bạn thêm vào chỉ đến một CSDL SQL Server Compact có tên School.sdf bên trong thư mục App_Data.

Khởi tạo CSDL với dữ liệu kiểm thử

Entity Framework có thể tự động tạo (hoặc xóa hay tạo lại) một CSDL cho bạn khi chạy ứng dụng. Bạn có thể yêu cầu điều này được thực hiện mỗi khi chạy ứng dụng hay chỉ khi mô hình dữ liệu không đồng bộ với CSDL. Bạn cũng có thể viết một lớp chứa một phương thức để Entity Framework tự động gọi sau khi tạo ra CSDL, điều này giúp bạn có thể đưa dữ liệu test vào CSDL một cách tự động. Trong phần này bạn sẽ chỉ ra CSDL phải được xóa và tạo lại một khi mô hình bị thay đổi.

Trong thư mục DAL, tạo một lớp mới có tên SchoolInitializer.cs và thay thế nội dung của nó với đoạn lệnh dưới đây, nó sẽ cho phép CSDL được tạo khi cần và nạp dữ liệu kiểm thử vào trong CSDL mới.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using ContosoUniversity.Models;

namespace ContosoUniversity.DAL
{
    public class SchoolInitializer : DropCreateDatabaseIfModelChanges<SchoolContext>
    {
        protected override void Seed(SchoolContext context)
        {
            var students = new List<Student>
            {
                new Student { FirstMidName = "Carson",   LastName = "Alexander", EnrollmentDate = DateTime.Parse("2005-09-01") },
                new Student { FirstMidName = "Meredith", LastName = "Alonso",    EnrollmentDate = DateTime.Parse("2002-09-01") },
                new Student { FirstMidName = "Arturo",   LastName = "Anand",     EnrollmentDate = DateTime.Parse("2003-09-01") },
                new Student { FirstMidName = "Gytis",    LastName = "Barzdukas", EnrollmentDate = DateTime.Parse("2002-09-01") },
                new Student { FirstMidName = "Yan",      LastName = "Li",        EnrollmentDate = DateTime.Parse("2002-09-01") },
                new Student { FirstMidName = "Peggy",    LastName = "Justice",   EnrollmentDate = DateTime.Parse("2001-09-01") },
                new Student { FirstMidName = "Laura",    LastName = "Norman",    EnrollmentDate = DateTime.Parse("2003-09-01") },
                new Student { FirstMidName = "Nino",     LastName = "Olivetto",  EnrollmentDate = DateTime.Parse("2005-09-01") }
            };
            students.ForEach(s => context.Students.Add(s));
            context.SaveChanges();

            var courses = new List<Course>
            {
                new Course { Title = "Chemistry",      Credits = 3, },
                new Course { Title = "Microeconomics", Credits = 3, },
                new Course { Title = "Macroeconomics", Credits = 3, },
                new Course { Title = "Calculus",       Credits = 4, },
                new Course { Title = "Trigonometry",   Credits = 4, },
                new Course { Title = "Composition",    Credits = 3, },
                new Course { Title = "Literature",     Credits = 4, }
            };
            courses.ForEach(s => context.Courses.Add(s));
            context.SaveChanges();

            var enrollments = new List<Enrollment>
            {
                new Enrollment { StudentID = 1, CourseID = 1, Grade = 1 },
                new Enrollment { StudentID = 1, CourseID = 2, Grade = 3 },
                new Enrollment { StudentID = 1, CourseID = 3, Grade = 1 },
                new Enrollment { StudentID = 2, CourseID = 4, Grade = 2 },
                new Enrollment { StudentID = 2, CourseID = 5, Grade = 4 },
                new Enrollment { StudentID = 2, CourseID = 6, Grade = 4 },
                new Enrollment { StudentID = 3, CourseID = 1            },
                new Enrollment { StudentID = 4, CourseID = 1,           },
                new Enrollment { StudentID = 4, CourseID = 2, Grade = 4 },
                new Enrollment { StudentID = 5, CourseID = 3, Grade = 3 },
                new Enrollment { StudentID = 6, CourseID = 4            },
                new Enrollment { StudentID = 7, CourseID = 5, Grade = 2 },
            };
            enrollments.ForEach(s => context.Enrollments.Add(s));
            context.SaveChanges();
        }
    }
}

Phương thức Seed nhận vào đối tượng context như một tham số, và đoạn code bên trong phương thức này sẽ dùng đối tượng context đó để thêm các thực thể vào CSDL. Với mỗi kiểu thực thể, đoạn lệnh sẽ tạo một tập hợp các thực thể mới, và thêm chúng vào trong thuộc tính DbSet tương ứng, sau đó lưu lại vào CSDL. Không cần thiết phải gọi SaveChanges() sau mỗi lần thêm một nhóm thực thể như chúng ta làm ở đây, nhưng làm như vậy sẽ giúp bạn xác định được lỗi trong quá trình ghi vào CSDL dễ dàng hơn.

Thêm các thay đổi sau vào file Global.asax.cs để các câu lệnh khởi tạo được chạy khi bắt đầu ứng dụng:

  • Thêm các phát biểu using:
    using System.Data.Entity; using ContosoUniversity.Models; using ContosoUniversity.DAL;
  • Trong phương thức Application_Start, gọi đến phương thức khởi tạo CSDL Entity Framework:
     Database.SetInitializer<SchoolContext>(new SchoolInitializer());

Bây giờ mỗi khi chạy ứng dụng, trong lần kết nối đầu tiên đến CSDL, Entity Framework sẽ so sánh CSDL với mô hình dữ liệu của bạn (lớp SchoolContext). Nếu có sự khác nhau, ứng dụng sẽ xóa và tạo lại CSDL.

Ghi chú: Khi đưa ứng dụng lên một máy chủ web chạy thật, bạn phải xóa các dòng lệnh nạp dữ liệu kiểm thử.

Giờ bạn sẽ tạo một trang web để hiển thị dữ liệu, và việc xử lý các yêu cầu dữ liệu sẽ tự động thực hiện việc tạo CSDL. Bạn sẽ bắt đầu bằng việc tạo một controller mới. Nhưng trước khi làm điều này, hãy build project để trình hỗ trợ tạo controller có thể tìm thấy được các lớp mô hình và lớp context của bạn.

Tạo Student Controller

Để tạo Student Controller, nhấn phải chuột lên thư mục Controllers trong cửa sổ Solution Explorer và chọn Add, sau đó chọn Controller. Trong hộp thoại Add Controller, đặt các giá trị giống như sau và nhân Add:

  • Controller name: StudentController.
  • Template: Controller with read/write actions and views, using Entity Framework. (Mặc nhiên)
  • Model class: Student (ContosoUniversity.Models). (Nếu không thấy mục này trong danh sách, hãy thử dịch và làm lại)
  • Data context class: SchoolContext (ContosoUniversity.Models).
  • Views: Razor (CSHTML). (Mặc nhiên)

Add_Controller_dialog_box_for_Student_controller

Mở file Controllers\StudentController.cs. You see a class variable has been created that instantiates a database context object: Bạn sẽ thấy một biến database context thuộc lớp đã được khai báo và khởi tạo.

private SchoolContext db = new SchoolContext();

Phương thức action Index trả về một danh sách các sinh viên từ thuộc tính Students của đối tượng database context:

 public ViewResult Index() {     return View(db.Students.ToList()); }

Trình hỗ trợ tạo controller cũng tạo cho bạn một tập các view cho lớp Student. Để tùy biến lại phần tiêu đề và thứ tự các cột trong view Index, mở file Views\Student\Index.cshtml và thay thế nội dung hiện có với đoạn lệnh sau:

@model IEnumerable<ContosoUniversity.Models.Student>

@{
    ViewBag.Title = "Students";
}

<h2>Students</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        <th></th>
        <th>Last Name</th>
        <th>First Name</th>
        <th>Enrollment Date</th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.StudentID }) |
            @Html.ActionLink("Details", "Details", new { id=item.StudentID }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.StudentID })
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.LastName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.FirstMidName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.EnrollmentDate)
        </td>
    </tr>
}

</table>

Chạy web site, nhấn vào tab Students, bạn sẽ thấy một danh sách các sinh viên.

Students_Index_page

Đóng cửa sổ trình duyệt. Trong Solution Explorer, chọn project ContosoUniversity (hãy chắc chắn là bạn chọn project chứ không phải solution). Nhấn Show all Files nếu chưa ở chế độ đó. Nhấn Refresh và mở phần App_Data để nhìn thấy file Shool.sdf.

School.sdf_file_in_Solution_Explorer

Nhấn đúp lên School.sdf. Sau đó mở thư mục Tables để xem các bảng đã được tạo trong CSDL.

Ghi chú: Nếu bạn gặp lỗi khi nhấn đúp chuột lên School.sdf, hãy kiểm tra lại để đảm bảo bạn đã cài Visual Studio 2010 SP1 Tools for SQL Server Compact 4.0. (Bạn có thể xem liên kết đến phần mềm này ở đầu trang). Nếu bây giờ bạn mới cài đặt nó, bạn sẽ phải đóng và mở lại Visual Studio.

Server_Explorer_showing_School_tables

Có một bảng cho mỗi tập thực thể, và thêm một bảng có tên EdmMetadata, bảng này được dùng bởi Entity Framework để xác định xem CSDL và mô hình có đồng bộ với nhau hay không.

Nhấn chuột phải lên một bảng và chọn Show Table Data để xem dữ liệu bên trong (được đưa vào bởi lớp SchoolInitializer).

Table_data_in_Student_table

Khi đã hoàn thành, hãy đóng kết nối lại. (Nếu không đóng, bạn có thể sẽ gặp lỗi trong lần chạy project tiếp theo).

Close_the_SQL_Compact_connection

Các quy ước

Khối lượng lệnh bạn phải viết để Entity Framework đủ để tạo một CSDL hoàn chỉnh là rất ít nhờ vào một số quy ước được đặt ra bởi Entity Framework. Một số trong chúng đã được nhắc đến như là:

  • Dạng số nhiều của tên lớp thực thể sẽ được dùng như tên bảng.
  • Tên các thuộc tính sẽ được dùng như tên cột.
  • Các thuộc tính có tên ID hay classnameID được coi là khóa chính.
  • Entity Framework kết nối đến CSDL của bạn bằng cách tìm chuỗi kết nối có cùng tên với lớp database context. (SchoolContext trong trường hợp này).

Bạn đã thấy các quy ước này cũng có thể bị thay đổi (ví dụ, bạn chỉ ra tên bảng không nên ở dạng số nhiều), và bạn sẽ học thêm về các quy ước cũng như cách thay thế chúng trong bài Creating a More Complex Data Model trong cùng loạt bài này.

Bạn đã tạo một ứng dụng đơn giản dùng ENTity Framework và SQL Server COMpact để lưu trữ và hiển thị dữ liệu. Trong phần tiếp theo bạn sẽ học các thực hiện các thao tác CRUD cơ bản (CRUD: create, read, update, delete).

Liên kết đến các tài nguyên khác của ENtity Framework có thể tìm thấy trong bài cuối cùng của loạt bài này.

Người dịch: Đào Hải Nam

Bài viết gốc: http://www.asp.net/entity-framework/tutorials/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application

14 thoughts on “Tạo một mô hình dữ liệu Entity Framework cho ứng dụng ASP.NET MVC

  1. Xin cám ơn bài dịch của anh,
    Em đang nghiên cứu cái này, và khi thực hiện theo có dính vài lỗi, một trong các lỗi này là:
    Khi thay đổi các file trong “models” ví dụ:

    public int OrderId { get; set; } (1)

    [ScaffoldColumn(false)] (2)
    public int OrderId { get; set; }

    Thì nó sẽ báo lỗi connect Database:
    [SqlException (0x80131904): Login failed for user ‘sa’.]
    System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject) +1316
    System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection) +108
    System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory) +126
    System.Data.SqlClient.SqlConnection.Open() +125
    System.Data.SqlClient.SqlProviderServices.UsingConnection(SqlConnection sqlConnection, Action`1 act) +85
    System.Data.SqlClient.SqlProviderServices.UsingMasterConnection(SqlConnection sqlConnection, Action`1 act) +204

    Và em phải xóa DB và run lại thì mới hết lỗi. vậy điều em muốn hỏi là, làm sao khi thay đổi cấu trúc trong các file “models” thì DB có thể Update, mà không cần xóa. Vì nếu trong quá trình triển khai khi DB có dữ liệu thực, mà ta muốn edit trường nào đó trong bảng nào đó thì cần phải giữ lại dữ liệu.
    Mong phản hồi của anh, em xin cám ơn!

  2. Theo tôi, cách tiếp cận Code First có thể không phù hợp với các CSDL thường thay đổi, hoặc cách tiếp cận “toàn bộ CSDL vào chung trong một mô hình”.

  3. Thanks Anh,
    Nhưng nó ko phải lỗi Login, vì nếu em xóa DB đó thì nó chạy ok (tự tạo lại DB). nhưng chỉ cần Edit một trường nào đó trong Models thì nó sẽ lỗi như thế.

  4. Anh ơi,
    “Code First không phù hợp với CSDL thường thay đổi”, nhưng em mới bắt đầu nghiên cứu MVC3, mà qua 2 Project hướng dẫn thì điều là “Code First”, anh có tài liệu nào khác nữa không ạ.
    Thanks Anh Nam!

  5. Theo mình nghĩ thì không phải “Code First không phù hợp với CSDL thường thay đổi” mà là model first mới không phù hợp. Code First chẳng qua là hình thức sử dụng lớp dbcontext thay vì ObjectContext để map db thành các class trong DAL. Khi bạn có sẵn database, cũng có thể chuyển từ dạng database first -> code first = cách sử dụng bộ sinh code DBcontext (EF 4.1) thay vì bộ sinh code mặc định là Entity object. Bởi vì các ứng dụng thực tế không bao giờ có chuyện database sinh ra từ Entity Model của EF.

    Mong anh Nam góp ý thêm

  6. Mog a giúp đỡ.
    hyperlink(xemchitiet) trong Asp.net làm sao liên kết với 1 cột(Noidungchitiet) của 1 table trong csdl?

  7. Anh Nam ơi cho em hỏi với code first em có thể tạo ra 1 bảng có primary key gồm 2 thuộc tính ko? Tạo như thế nào. Cảm ơn anh.

  8. Nếu ai bị lỗi ASP.NET MVC 3 – Unable to find the requested .Net Framework Data Provider
    lúc tạo Controller đoạn cuối thì … http://www.microsoft.com/en-us/sqlserver/editions/2012-editions/compact.aspx có thể down bản mới nhất về cài hay làm theo cách này : hiệu quả , mà ko biết lí do … Để ai đi sau nếu lỗi khỏi kiếm …
    I was having the same problem so I replaced

    with the following

    And it worked enough to let me continue working. I too would also eventually learn how to make these kinds of applications work with mysql at some point, but for now this should at least help you continue with the tutorial.
    Cũng cám ơn chủ thớt bỏ công ra dịch …. Em đã thử ok …

  9. “Unable to find the requested .Net Framework Data Provider” là lỗi không tìm thấy EF Data Provider. Tùy vào đang dùng provider nào (SQL Server, MySQL) thì sẽ có cách xử lý khác nhau, nhưng đơn giản nhất là download provider đó về cài lại😀.

  10. Em là 1 sinh viên mới ra trường, cám ơn anh rất nhiều đã chia sẻ những kiến thức rất có ích với những người như em🙂

  11. Chào bạn, mình có một thắc mắc như thế này: làm sao chúng ta có thể biểu diễn các mối quan hệ dữ liệu với Code First : các quan hệ one-many, one-one hay là aggragation được không ?

  12. Mình đang làm phần này…gặp trục trặc ở phần add StudentController….mình làm đúng từng bước xong rồi bấm ADD thì nó báo lỗi :unable to retrieve metadata for “ContosoUniversity.Model.Student”.unable to find the requested .Net Framework Data Provider.it may not be installed……Giúp mình sớm vợi nhé…thanks !

Gửi phản hồi

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s