Giới thiệu tổng quan, kiến trúc Entity Framework

    0

    Entity Framework là một thư viện ORM – một loại chương trình giúp ánh xạ qua lại giữa các object của chương trình và bản ghi/bảng của cơ sở dữ liệu quan hệ – được Microsoft phát triển từ 2008. Entity Framework là công cụ làm việc với cơ sở dữ liệu được Microsoft khuyến nghị.

    Nếu bạn đã từng nghe nói về Entity Framework, bạn hẳn cũng biết sơ qua những ưu điểm của nó so với trực tiếp sử dụng ADO.NET. Một vài trong số những đặc điểm của Entity Framework là dễ học, dễ sử dụng và không cần biết đến ngôn ngữ SQL. Sự đơn giản này khiến nhiều bạn lầm tưởng rằng chỉ cần đọc sơ qua vài bài blog post là có thể làm việc ngon lành với Entity Framework.

    Không lẽ nào một framework mạnh mẽ, uyển chuyển mà chỉ cần học mót vài buổi đã xong!?! Vậy các cuốn sách dạy lập trình Entity Framework dày vài trăm trang viết cái gì mà lắm vậy? Còn những vấn đề gì bạn chưa từng nghe thấy? Phải biết những gì mới đủ làm project? Bạn có biết Entity Framework có 3 cách tiếp cận (Code-first, Database-first, Model-first), vậy cách nào phù hợp với dự án của bạn?

    Còn rất rất nhiều câu hỏi như thế nữa. Bạn đã biết hết chưa? Hãy đọc nốt loạt bài giảng này và bạn sẽ hiểu.

    Trước hết, bài học đầu tiên này sẽ giới thiệu tổng quan, kiến trúc và cách cài đặt Entity Framework cho project C#. Đây là cơ sở quan trọng để bạn có cái nhìn toàn cảnh về EF trước khi đi tiếp vào các vấn đề chuyên sâu của lập trình Entity Framework.

    Quay trở lại Tự học lập trình ADO.NET và Entity Framework

    Entity Framework là gì?

    Vài dòng về lịch sử Entity Framework

    Entity Framework ra đời từ 2008 cùng với .NET 3.5. Phiên bản hiện nay là 6.0. Có một số mốc đặc biệt trong lịch sử framework này.

    Phiên bản đầu tiên chỉ hỗ trợ hướng tiếp cận Database-first. Nghĩa là EF lúc đó chỉ có thể làm việc với một cơ sở dữ liệu sẵn có. EF giúp sinh code các lớp model bằng C# hoặc VB.NET.

    Đến phiên bản 4 xuất hiện hướng tiếp cận Model-first, giúp thiết kế các lớp thực thể trước sử dụng giao diện đồ họa.

    Phiên bản 4.1 đưa thêm hướng tiếp cận Code-first, nghĩa là từ giờ mọi thứ được viết bằng code VB.NET hoặc C# ngay từ đầu, một hướng tiếp cận được lập trình viên hoan nghênh đặc biệt.

    Hiện nay bạn có thể nghe thấy thêm Entity Framework Core. Entity Framework Core và Entity Framework Framework là hai thư viện khác nhau, sử dụng cho hai nền tảng .NET khác nhau.

    Ba hướng tiếp cận này sẽ được trình bày chi tiết hơn ở phần sau.

    Entity Framework là một ORM

    Hẳn bạn không ít lần nghe thấy cụm ký tự ORM. ORM là viết tắt của Object – Relational Mapper (hay Mapping, tùy từng tình huống). ORM là một tập hợp các công nghệ cho phép làm việc với các hệ quản trị cơ sở dữ liệu quan hệ (Relational Database Management System, hay RDBMS) từ các ngôn ngữ hướng đối tượng và không cần trực tiếp xử lý truy vấn SQL.

    Các RDBMS phổ biến bao gồm Oracle, SQL Server, DB2, MySQL.

    Các ORM như Entity Framework hỗ trợ người lập trình ánh xạ (hai chiều): class với cấu trúc bảng; object với bản ghi (hay hàng) trong bảng; thuộc tính (property) với cột của bảng; tập hợp object với tập hợp các bản ghi; tham chiếu sang object với quan hệ giữa các bảng. Trong quá trình này, tất cả các truy vấn SQL được ORM tự động sinh ra và thực thi. Người lập trình chỉ cần làm việc với các khái niệm quen thuộc của ngôn ngữ lập trình hướng đối tượng.

    Trong quá trình ánh xạ này, ORM hỗ trợ tự động xử lý sự vênh nhau giữa ngôn ngữ lập trình hướng đối tượng và cơ sở dữ liệu quan hệ. Sự vênh nhau này bao gồm: vênh về kiểu giữa .NET và RDBMS; vênh về cách lưu trữ (giữa bảng và object trong bộ nhớ); Mối quan hệ phức tạp giữa các object và quan hệ giữa các bảng. Các vấn đề này thường gọi chung là impedance mismatch (chả biết dịch là gì!).

    Entity Framework có đặc điểm gì quan trọng

    Hãy đọc phần này để có cảm nhận chung về Entity Framework với tư cách một ORM.

    Với vai trò là một ORM, Entity Framework thể hiện cơ sở dữ liệu dưới dạng tập hợp của các object quen thuộc.

    Trước hết, cả cơ sở dữ liệu được thể hiện bằng một lớp con của lớp DbContext. Mỗi bảng dữ liệu sẽ thể hiện bằng một object của DbSet<T>. Mỗi hàng trong bảng thể hiện bằng một object của lớp thực thể bạn xây dựng. Mỗi cột thể hiện bằng một thuộc tính của object. Tất cả những thao tác ánh xạ này có thể được thực hiện hoàn toàn tự động hoặc bạn có thể can thiệp vào để thực hiện theo ý mình.

    Thứ hai, bạn có thể truy vấn dữ liệu sử dụng LINQ, thay vì dùng SQL. Bạn có thể dễ dàng thực hiện các truy vấn CRUD hoàn toàn từ code C# với các class quen thuộc mà không cần viết dòng SQL nào.

    Thứ ba, bạn có thể thực hiện các thao tác với cấu trúc dữ liệu như tạo cơ sở dữ liệu, tạo bảng, thay đổi cấu trúc bảng một cách dễ dàng với công cụ Migration mà không làm mất dữ liệu.

    Sử dụng Entity Framework có ưu điểm gì

    Đây là những câu trả lời cho câu hỏi “Tại sao cần dùng một ORM như Entity Framework?”.

    Thứ nhất là tăng năng suất thông qua giảm số lượng code. Các kinh nghiệm thực tế cho thấy khoảng 35% code của chương trình thường là để làm việc với cơ sở dữ liệu. Nếu dùng một ORM tốt có thể cắt giảm con số này xuống chỉ còn 15-20%. Cá biệt có thể chỉ còn 5%.

    Thứ hai là giảm sự phức tạp khi bảo trì phần mềm. Ít code hơn đồng nghĩa với dễ bảo trì hơn, đặc biệt là về dài hạn. Việc bảo trì này có thể thực hiện cả ở phía cơ sở dữ liệu và phía ứng dụng mà không phải lo code lại.

    Thứ ba, Entity Framework được đặt trong .NET Framework và tích hợp trong Visual Studio. Yếu tố này giúp làm việc với EF càng đơn giản và tiện lợi hơn rất nhiều. Đây cũng là lý do nhiều người lựa chọn EF thay cho NHibernate, một ORM khác cũng rất phổ biến cho .NET. Entity Framework cũng là ORM được Microsoft khuyến nghị sử dụng. Công ty đã đầu tư rất nhiều để phát triển ORM này.

    Tuy vậy, việc sử dụng một ORM như Entity Framework có một nhược điểm về hiệu suất. Đây cũng là chủ đề gây tranh nhiều trên mạng. Do ORM thường rất phức tạp, việc sử dụng chúng đương nhiên dẫn đến giảm hiệu suất nếu so với trực tiếp sử dụng ADO.NET. Tuy nhiên, yếu tố này nên đặt trong sự so sánh với những lợi ích nó đem lại.

    Kiến trúc Entity Framework

    Entity Framework có kiến trúc tương đối lằng nhằng. Bạn nên đọc để hiểu. Điều này giúp ích rất nhiều khi học sâu hơn về nó.

    Kiến trúc Entity Framework
    Kiến trúc Entity Framework

    Như trong sơ đồ trên bạn thấy Entity Framework phân chia làm các thành phần: Entity Data Model (EDM), Entity Client data provider, Object Services, LINQ to Entities và Entity SQL.

    Tất cả các thành phần này nằm bên trên Data provider của ADO.NET mà bạn đã biết. Trong đó Data provider chịu trách nhiệm làm việc (về mặt vật lý) với RDBMS cụ thể. Đây cũng là lý do trong các bài học về lập trình ADO.NET cơ bản chúng ta chỉ xem xét thành phần này.

    Như đã trình bày khi nói về kiến trúc ADO.NET, thư viện này bao gồm hai phần quan trọng là Data provider (thành phần connected) và thành phần disconnected (DataSet, DataTable, v.v.). Hai thành phần này tương tác qua DataAdapter.

    Chúng ta sẽ nói qua về mỗi thành phần một chút thôi.

    Entity Data Model (EDM)

    EDM là thành phần lưu trữ thông tin ánh xạ (mapping) giữa các class và cơ sở dữ liệu. Nó đóng vai trò cầu nối giữa các lớp model và cơ sở dữ liệu nhưng lại giúp chương trình hoàn toàn tách biệt với cơ sở dữ liệu.

    Nghe hơi chướng tai phải không ạ!

    Cơ sở dữ liệu và các lớp model của chương trình là hai thứ khác nhau hoàn toàn về bản chất và cấu trúc. Nhờ có EDM, hai thứ khác nhau này được liên kết với nhau. Nếu bạn thay một cơ sở dữ liệu khác, EDM lại giúp bạn tạo cầu nối mới mà không phải thay đổi các lớp model. Như vậy chương trình không phụ thuộc vào cơ sở dữ liệu.

    EDM có 3 thành phần (thực ra chỉ là 3 file xml):

    • Conceptual model (đuôi csdl): chịu trách nhiệm lưu thông tin về các lớp model và quan hệ giữa chúng;
    • Storage model (đuôi ssdl): lưu thông tin về cơ sở dữ liệu, bao gồm các bảng, view, stored procedure, khóa, quan hệ;
    • Mapping model (đuôi msl): lưu thông tin ánh xạ giữa conceptual và storage model.

    Thông tin từ các file này được sử dụng để cung cấp metadata cho các thành phần còn lại.

    Một điều vô cùng may mắn là EDM hầu như được tạo tự động hết. Dĩ nhiên, bạn có thể tự thay đổi cho phù hợp với yêu cầu của mình.

    LINQ to Entities và Entity SQL

    Đây là hai ngôn ngữ dùng để truy vấn dữ liệu.

    Sở dĩ có 2 ngôn ngữ truy vấn là vì Entity Framework đã xây dựng trước. Entity SQL được tạo ra làm ngôn ngữ truy vấn. Sau đó LINQ mới ra đời và đội ngũ phát triển Entity Framework đưa LINQ to Entities vào EF.

    Nếu đã quen thuộc với LINQ thì bạn tiếp có thể tục sử dụng nó cho LINQ to Entities vì nó rất giống nhau. Bạn không cần học Entity SQL làm gì. Entity SQL có cú pháp nhìn hơi khó chịu.

    LINQ to Entities được xem như là một “phương ngữ” của LINQ. Không phải mọi thứ trong LINQ đều sử dụng được trong LINQ to Entities.

    Object services

    Đây là cánh cổng để truy xuất dữ liệu. Tầng này thực hiện một quá trình gọi là materialization – quá trình chuyển đổi dữ liệu dạng bảng nhận từ tầng dưới (Entity Client data provider) về dạng object. Lưu ý rằng, dữ liệu dạng bảng nhận từ tầng dưới không phải là dữ liệu dạng bảng thu trực tiếp từ cơ sở dữ liệu (gọi là database tabular structure) mà là một dạng trung gian có tên gọi là model tabular structure.

    Ngoài ra tầng này cũng đảm nhiệm việc quản lý trạng thái (state management). Hiểu một cách đơn giản, đây là việc theo dõi các thay đổi (change tracking) của từng object. Quản lý trạng thái có vai trò đặc biệt quan trọng khi thực hiện các thao tác thêm mới, cập nhật, xóa bỏ dữ liệu. Nhờ có nó bạn thoải mái thực hiện các thao tác trên dữ liệu và lưu lại tất cả thay đổi chỉ với một dòng code!

    Entity Client data provider

    Tầng này chịu trách nhiệm tương tác với Data provider của ADO.NET. Tầng này thực hiện chuyển đổi truy vấn LINQ to Entities hoặc Entity SQL về truy vấn SQL. Sau đó Data provider sẽ thực thi truy vấn SQL. Như bạn đã biết, Data provider chịu trách nhiệm tương tác về mặt vật lý với cơ sở dữ liệu.

    Một nhiệm vụ khác của Entity Client là chuyển đổi kết quả thu được từ truy vấn SQL về một dạng trung gian (model tabular structure). Kết quả trung gian này chuyển lên cho Object Services xử lý.

    Việc thực thi và đọc kết quả truy vấn này phải sử dụng đến hai người bạn quen thuộc của ADO.NET là Command và Parameter mà chúng ta đã từng làm việc cùng.

    Làm việc với Entity Framework

    Các giai đoạn làm việc Entity Framework

    Nếu nhớ lại kiến trúc Entity Framework vừa trình bày ở phần trên bạn sẽ thấy nó phân chia làm hai khối rõ ràng:

    Kiến trúc Entity Framework
    Kiến trúc Entity Framework

    Hai khối này liên quan đến hai giai đoạn làm việc với Entity Framework: (1) Xây dựng Entity Data Model; (2) Truy vấn và xử lý dữ liệu.

    Ở giai đoạn xây dựng EDM bạn có bốn cách tiếp cận khác nhau: Database-first, Model-first, Code-first, Code-first from Database. Lựa chọn cách nào phụ thuộc vào từng điều kiện cụ thể. Dù chọn cách nào, cuối cùng bạn cũng thu được đủ bộ Entity Data Model (EDM). Tuy nhiên cái bạn trực tiếp sử dụng trong chương trình chỉ là thành phần Conceptual Model.

    Việc lựa chọn hướng tiếp cận xây dựng EDM không có ảnh hưởng gì đến giai đoạn xử lý.

    Ở giai đoạn xử lý dữ liệu, bạn sử dụng LINQ to Entities và Object Services để làm việc với dữ liệu dựa trên EDM đã xây dựng. Trong đó: LINQ to Entities giúp truy vấn (đọc dữ liệu); Object Services giúp thực hiện các thao tác theo dõi và ghi dữ liệu. Bạn cũng không bao giờ phải tương tác các tầng bên dưới.

    Nhìn lại sơ đồ kiến trúc trên, cái mà bạn trực tiếp làm việc cùng (Conceptual Model, LINQ to Entities, Object Services) là lớp trên cùng và đều được tô màu vàng.

    Object Services từ EF 4.1 được đơn giản hóa và gọi là DbContext API. Loạt tính năng của DbContext API được cung cấp bởi nhóm class DbContext, DbSet và DbQuery.

    Vì có sự phân chia giai đoạn tương đối rõ ràng như trên, bài giảng này của chúng ta cũng có hai phần chính. Một phần liên quan đến xây dựng EDM. Phần thứ hai hướng dẫn cách sử dụng DbContext API để xử lý dữ liệu.

    Các hướng tiếp cận khi xây dựng EDM

    Database-first

    Đây là hướng tiếp cận xuất hiện đầu tiên trong Entity Framework.

    Hướng tiếp cận này sẽ giúp sinh ra model từ cơ sở dữ liệu có sẵn, từ stored procedures hoặc views. Bạn chỉ cần tinh chỉnh lại model (domain classes) theo nhu cầu của mình là xong. Việc tinh chỉnh này thực hiện qua một giao diện đồ họa (visual designer) rất tiện lợi. Nói cách khác, bạn xuất phát từ Storage Model có sẵn, EF sẽ giúp bạn sinh ra Conceptual Model và Mapping.

    Model-first

    Đây là hướng tiếp cận thứ hai xuất hiện từ EF4. Hướng tiếp cận này cho phép bạn sử dụng một giao diện đồ họa để thiết kế model trước. Sau đó trình thiết kế này sẽ sinh ra các lớp model tương ứng cũng như mã SQL để tạo cơ sở dữ liệu. Nói cách khác, bạn xuất phát từ một giao diện thiết kế riêng biệt. EF sẽ giúp bạn sinh ra cả ba thành phần của EDM.

    Code-first

    Đây là hướng tiếp cận được lập trình viên hoan nghênh nhất. Code-first xuất hiện từ EF4.1.

    Với vai trò lập trình viên, bạn không cần quan tâm đến SQL hay giao diện thiết kế đồ họa nữa. Tất cả những gì cần làm là xây dựng các lớp model (domain classes) theo đúng kiểu hướng đối tượng mà bạn quen thuộc nhất. Entity Framework sẽ làm tất cả những gì còn lại để bạn có một cơ sở dữ liệu phù hợp. Nói theo kiểu khác, bạn tự mình code Conceptual Model, EF sẽ giúp bạn sinh ra Mapping và Storage Model.

    Code-first cũng là hướng tiếp cận chúng ta sẽ tiếp cận đầu tiên và tập trung nhiều thời gian nhất.

    Code-first from Database

    Đây là một cách tiếp cận khá khác biệt. Bạn xuất phát từ một cơ sở dữ liệu có sẵn. EF giúp bạn sinh ra Conceptual Model và Mapping.

    Tuy nhiên, cái bạn thu được chỉ là code (của các domain class) chứ không có giao diện thiết kế (đồ họa) như kiểu tiếp cận Database-first.

    Dưới đây là so sánh hình tượng ba cách tiếp cận:

    Hướng tiếp cận database-first
    Database-first

    Hướng tiếp cận model-first
    Model-first

    Hướng tiếp cận code-first
    Code-first

    Kết luận

    Bài học này đã cung cấp cho bạn một cái nhìn toàn cảnh về Entity Framework. Mặc dù không có thực hành gì nhưng những kiến thức ở bài học này đóng vai trò nền tảng để bạn có thể đi sâu tiếp vào từng vấn đề chi tiết.

    Nếu có thắc mắc hoặc cần trao đổi thêm, mời bạn viết trong phần Bình luận ở cuối trang. Nếu cần trao đổi riêng, hãy gửi email hoặc nhắn tin qua form liên hệ. Nếu bài viết hữu ích với bạn, hãy giúp chúng tôi chia sẻ tới mọi người. Cảm ơn bạn!

    Bình luận

    avatar
      Đăng ký theo dõi  
    Thông báo về