{"id":3261,"date":"2017-02-26T12:30:21","date_gmt":"2017-02-26T12:30:21","guid":{"rendered":"http:\/\/www.rezafaisal.net\/?p=3261"},"modified":"2017-02-26T12:32:00","modified_gmt":"2017-02-26T12:32:00","slug":"relational-database-modeling-data-annotations-vs-fluent-api","status":"publish","type":"post","link":"http:\/\/www.rezafaisal.net\/?p=3261","title":{"rendered":"Relational Database Modeling: Data Annotations vs Fluent API"},"content":{"rendered":"<p>Entity Framework adalah framework untuk mempermudah mengakses database. Framework ini awalnya dibangun sebagai bagian dari .NET framework yang hanya dapat digunakan pada platform Microsoft. Tetapi dengan dikembangkannya .NET Core yang bersifat multiplatform, maka Entity Framework Core juga dapat digunakan pada berbagai platform.<\/p>\n<p>Entity Framework Core atau disingkat EF Core adalah object-relational mapper (OR\/M) yang memungkinkan software developer dapat bekerja dengan database dengan object .NET. Hal ini mengurangi kode program untuk mengakses database, karena digantikan oleh class dan method yang telah disediakan oleh framework ini.<\/p>\n<p>Sebagai contoh jika dimiliki tabel seperti pada gambar di bawah ini.<\/p>\n<p><a href=\"http:\/\/www.rezafaisal.net\/wp-content\/uploads\/2017\/02\/01-6.jpg\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border: 0px;\" title=\"01\" src=\"http:\/\/www.rezafaisal.net\/wp-content\/uploads\/2017\/02\/01_thumb-6.jpg\" alt=\"01\" width=\"550\" height=\"209\" border=\"0\" \/><\/a><\/p>\n<p>Karenan EF \u201cmenganut azas\u201d penggunaan OR\/M, maka tabel-tabel di atas harus dibuat modelnya dalam bentuk class-class model yang dikenal dengan class entity model.\u00a0 Jumlah class yang harus dibuat adalah sesuai dengan jumlah tabel.\u00a0 Pada kasus di atas, artinya harus dibuat 4 class entity sebagai berikut.<\/p>\n<p>Class Authors.<\/p>\n<div id=\"codeSnippetWrapper\" style=\"font-size: 8pt; overflow: auto; cursor: text; font-family: 'Courier New', courier, monospace; width: 97.5%; direction: ltr; text-align: left; margin: 20px 0px 10px; line-height: 12pt; max-height: 200px; background-color: #f4f4f4; border: silver 1px solid; padding: 4px;\">\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span style=\"color: #0000ff;\">using<\/span> System;<\/pre>\n<p><span style=\"color: #0000ff;\">namespace<\/span> EFCoreGuestBook.Models<br \/>\n{<br \/>\n<span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">partial<\/span> <span style=\"color: #0000ff;\">class<\/span> Authors{<br \/>\n<span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">int<\/span> AuthorID {set; get;}<br \/>\n<span style=\"color: #0000ff;\">public<\/span> String Name {set; get;}<br \/>\n<span style=\"color: #0000ff;\">public<\/span> String Email {set; get;}<br \/>\n}<br \/>\n}<\/p>\n<p>&nbsp;<\/p>\n<\/div>\n<p>Class Categories.<\/p>\n<div id=\"codeSnippetWrapper\" style=\"font-size: 8pt; overflow: auto; cursor: text; font-family: 'Courier New', courier, monospace; width: 97.5%; direction: ltr; text-align: left; margin: 20px 0px 10px; line-height: 12pt; max-height: 200px; background-color: #f4f4f4; border: silver 1px solid; padding: 4px;\">\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span style=\"color: #0000ff;\">using<\/span> System;<\/pre>\n<p><span style=\"color: #0000ff;\">namespace<\/span> EFCoreGuestBook.Models<br \/>\n{<br \/>\n<span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">partial<\/span> <span style=\"color: #0000ff;\">class<\/span> Categories{<br \/>\n<span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">int<\/span> CategoryID {set; get;}<br \/>\n<span style=\"color: #0000ff;\">public<\/span> String Name {set; get;}<br \/>\n}<br \/>\n}<\/p>\n<p>&nbsp;<\/p>\n<\/div>\n<p>Class Books.<\/p>\n<div id=\"codeSnippetWrapper\" style=\"font-size: 8pt; overflow: auto; cursor: text; font-family: 'Courier New', courier, monospace; width: 97.5%; direction: ltr; text-align: left; margin: 20px 0px 10px; line-height: 12pt; max-height: 200px; background-color: #f4f4f4; border: silver 1px solid; padding: 4px;\">\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span style=\"color: #0000ff;\">using<\/span> System;<\/pre>\n<p><span style=\"color: #0000ff;\">namespace<\/span> EFCoreGuestBook.Models<br \/>\n{<br \/>\n<span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">partial<\/span> <span style=\"color: #0000ff;\">class<\/span> Books{<br \/>\n<span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">int<\/span> ISBN {set; get;}<br \/>\n<span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">int<\/span> CategoryID {set; get;}<br \/>\n<span style=\"color: #0000ff;\">public<\/span> String Title {set; get;}<br \/>\n<span style=\"color: #0000ff;\">public<\/span> String Photo {set; get;}<br \/>\n<span style=\"color: #0000ff;\">public<\/span> DateTime PublishDate {set; get;}<br \/>\n<span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">double<\/span> Price {set; get;}<br \/>\n<span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">int<\/span> Quantity {set; get;}<br \/>\n}<br \/>\n}<\/p>\n<p>&nbsp;<\/p>\n<\/div>\n<p>Class BooksAuthors.<\/p>\n<div id=\"codeSnippetWrapper\" style=\"font-size: 8pt; overflow: auto; cursor: text; font-family: 'Courier New', courier, monospace; width: 97.5%; direction: ltr; text-align: left; margin: 20px 0px 10px; line-height: 12pt; max-height: 200px; background-color: #f4f4f4; border: silver 1px solid; padding: 4px;\">\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span style=\"color: #0000ff;\">using<\/span> System;<\/pre>\n<p><span style=\"color: #0000ff;\">namespace<\/span> EFCoreGuestBook.Models<br \/>\n{<br \/>\n<span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">partial<\/span> <span style=\"color: #0000ff;\">class<\/span> BooksAuthors{<\/p>\n<p><span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">int<\/span> ISBN {set; get;}<\/p>\n<p><span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">int<\/span> AuthorID {set; get;}<br \/>\n}<br \/>\n}<\/p>\n<p>&nbsp;<\/p>\n<\/div>\n<p>Setelah class entity model dibuat, maka langkah selanjutnya adalah menentukan class model mana yang akan merepresentasikan suatu table pada database.\u00a0 Kemudian harus ditentukan juga property-property dari class akan menjadi representasi dari attribut-attribut table yang mana.\u00a0 Untuk melakukan mapping class dengan table yang ada pada database dapat dilakukan dengan dua cara, yaitu:<\/p>\n<ul>\n<li>Data Annotations, cara dilakukan dengan cara menambahkan \u201catribut\u201d di dalam file class yang telah dibuat di atas.<\/li>\n<li>Fluent API, cara ini dilakukan dengan cara menuliskan program terpisah dari class yang telah dibuat di atas.<\/li>\n<\/ul>\n<p>{<strong><em>Data Annotations<\/em><\/strong>}<\/p>\n<p>Untuk menggunakan cara ini, maka pada setiap class entity model di atas harus ditambahkan baris berikut ini.<\/p>\n<div id=\"codeSnippetWrapper\" style=\"font-size: 8pt; overflow: auto; cursor: text; font-family: 'Courier New', courier, monospace; width: 97.5%; direction: ltr; text-align: left; margin: 20px 0px 10px; line-height: 12pt; max-height: 200px; background-color: #f4f4f4; border: silver 1px solid; padding: 4px;\">\n<pre id=\"codeSnippet\" style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span style=\"color: #0000ff;\">using<\/span> System.ComponentModel.DataAnnotations;\r\n<span style=\"color: #0000ff;\">using<\/span> System.ComponentModel.DataAnnotations.Schema;<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<p>Selanjutnya untuk mapping class Categories ke table categories digunakan atribut [Table(&#8220;categories&#8221;)] yang dituliskan di atas nama class.\u00a0 Sedangkan untuk memetakan property class CategoryID dengan atribut category_id pada table digunakan atribut [Column(&#8220;category_id&#8221;)] yang diletakkan di atas baris property CategoryID.\u00a0 Sedangkan untuk menyatakan property CategoryID sebagai primary key, digunakan attribut [Key].\u00a0 Sehingga dapat dilihat kode lengkap class Categories sebagai berikut ini.<\/p>\n<div id=\"codeSnippetWrapper\" style=\"font-size: 8pt; overflow: auto; cursor: text; font-family: 'Courier New', courier, monospace; width: 97.5%; direction: ltr; text-align: left; margin: 20px 0px 10px; line-height: 12pt; max-height: 200px; background-color: #f4f4f4; border: silver 1px solid; padding: 4px;\">\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span style=\"color: #0000ff;\">using<\/span> System;\r\n<span style=\"color: #0000ff;\">using<\/span> System.ComponentModel.DataAnnotations;\r\n<span style=\"color: #0000ff;\">using<\/span> System.ComponentModel.DataAnnotations.Schema;<\/pre>\n<p><span style=\"color: #0000ff;\">namespace<\/span> EFCoreGuestBook.Models<br \/>\n{<br \/>\n[Table(<span style=\"color: #006080;\">&#8220;categories&#8221;<\/span>)]<br \/>\n<span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">partial<\/span> <span style=\"color: #0000ff;\">class<\/span> Categories{<br \/>\n[Key]<br \/>\n[Column(<span style=\"color: #006080;\">&#8220;category_id&#8221;<\/span>)]<br \/>\n<span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">int<\/span> CategoryID {set; get;}<\/p>\n<p>[Column(<span style=\"color: #006080;\">&#8220;name&#8221;<\/span>)]<br \/>\n<span style=\"color: #0000ff;\">public<\/span> String Name {set; get;}<br \/>\n}<br \/>\n}<\/p>\n<p>&nbsp;<\/p>\n<\/div>\n<p>Tetapi data annotation mempunyai keterbatasan yaitu:<\/p>\n<ul>\n<li>Tidak mendukung \u201ccomputed column\u201d atau kolom yang nilainya dihitung atau ditentukan pada database.<\/li>\n<li>Tidak mendukung \u201csequence\u201d.<\/li>\n<li>Tidak mendukung \u201cdefault value\u201d atau pemberian nilai default jika nilai suatu kolom tidak diberikan.<\/li>\n<li>Tidak mendukung \u201cindex\u201d.<\/li>\n<li>Tidak mendukung \u201cforeign key contraint\u201d yang digunakan untuk relasi antar model.<\/li>\n<li>Tidak mendukung \u201cprimary key\u201d lebih dari satu.<\/li>\n<\/ul>\n<p>Untuk menutupi kekurangan tersebut maka dapat digunakan Fluent API.<\/p>\n<p>{<strong><em>Fluent API<\/em><\/strong>}<\/p>\n<p>Fluent API adalah cara lain untuk melakukan konfigurasi class entity model untuk melakukan mapping class ke table.\u00a0 Cara kerja Fluent API ini berbeda dengan cara data annotation yang telah dilakukan di atas.\u00a0 Cara Fluent API tidak akan menyentuh dan mengubah isi dari class entity model seperti yang dilakukan oleh cara data annotation.\u00a0 Cara ini akan melakukan mapping dan konfigurasi pada file terpisah.\u00a0 Biasanya mapping dan konfigurasi dilakukan di dalam file class data context.\u00a0 Berikut ini adalah contoh class data context untuk mengelola class-class entity model di atas.<\/p>\n<div id=\"codeSnippetWrapper\" style=\"font-size: 8pt; overflow: auto; cursor: text; font-family: 'Courier New', courier, monospace; width: 97.5%; direction: ltr; text-align: left; margin: 20px 0px 10px; line-height: 12pt; max-height: 200px; background-color: #f4f4f4; border: silver 1px solid; padding: 4px;\">\n<div id=\"codeSnippet\" style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\">\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum1\" style=\"color: #606060;\">   1:<\/span> <span style=\"color: #0000ff;\">using<\/span> Microsoft.EntityFrameworkCore;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum2\" style=\"color: #606060;\">   2:<\/span> <span style=\"color: #0000ff;\">using<\/span> MySQL.Data.EntityFrameworkCore.Extensions;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum3\" style=\"color: #606060;\">   3:<\/span> <span style=\"color: #0000ff;\">using<\/span> Microsoft.Extensions.Configuration;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum4\" style=\"color: #606060;\">   4:<\/span><\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum5\" style=\"color: #606060;\">   5:<\/span> <span style=\"color: #0000ff;\">namespace<\/span> EFCoreGuestBook.Models{<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum6\" style=\"color: #606060;\">   6:<\/span>     <span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">class<\/span> BookStoreDataContext : DbContext<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum7\" style=\"color: #606060;\">   7:<\/span>     {<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum8\" style=\"color: #606060;\">   8:<\/span>         <span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">static<\/span> <span style=\"color: #0000ff;\">string<\/span> ConnectionString { get; set; }<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum9\" style=\"color: #606060;\">   9:<\/span><\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum10\" style=\"color: #606060;\">  10:<\/span>         <span style=\"color: #0000ff;\">protected<\/span> <span style=\"color: #0000ff;\">override<\/span> <span style=\"color: #0000ff;\">void<\/span> OnConfiguring(DbContextOptionsBuilder optionsBuilder)<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum11\" style=\"color: #606060;\">  11:<\/span>         {<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum12\" style=\"color: #606060;\">  12:<\/span>             optionsBuilder.UseMySQL(ConnectionString);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum13\" style=\"color: #606060;\">  13:<\/span>         }<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum14\" style=\"color: #606060;\">  14:<\/span><\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum15\" style=\"color: #606060;\">  15:<\/span>         <span style=\"color: #0000ff;\">protected<\/span> <span style=\"color: #0000ff;\">override<\/span> <span style=\"color: #0000ff;\">void<\/span> OnModelCreating(ModelBuilder modelBuilder)<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum16\" style=\"color: #606060;\">  16:<\/span>         {<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum17\" style=\"color: #606060;\">  17:<\/span>             modelBuilder.Entity&lt;Categories&gt;(entity =&gt;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum18\" style=\"color: #606060;\">  18:<\/span>             {<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum19\" style=\"color: #606060;\">  19:<\/span>                 entity.Property(e =&gt; e.CategoryID).HasColumnName(<span style=\"color: #006080;\">\"category_id\"<\/span>);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum20\" style=\"color: #606060;\">  20:<\/span>                 entity.Property(e =&gt; e.Name).HasColumnName(<span style=\"color: #006080;\">\"name\"<\/span>);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum21\" style=\"color: #606060;\">  21:<\/span>             });<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum22\" style=\"color: #606060;\">  22:<\/span>             modelBuilder.Entity&lt;Categories&gt;().HasKey(e =&gt; <span style=\"color: #0000ff;\">new<\/span> { e.CategoryID});<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum23\" style=\"color: #606060;\">  23:<\/span><\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum24\" style=\"color: #606060;\">  24:<\/span>             modelBuilder.Entity&lt;Authors&gt;(entity =&gt;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum25\" style=\"color: #606060;\">  25:<\/span>             {<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum26\" style=\"color: #606060;\">  26:<\/span>                 entity.Property(e =&gt; e.AuthorID).HasColumnName(<span style=\"color: #006080;\">\"author_id\"<\/span>);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum27\" style=\"color: #606060;\">  27:<\/span>                 entity.Property(e =&gt; e.Name).HasColumnName(<span style=\"color: #006080;\">\"name\"<\/span>);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum28\" style=\"color: #606060;\">  28:<\/span>                 entity.Property(e =&gt; e.Email).HasColumnName(<span style=\"color: #006080;\">\"email\"<\/span>);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum29\" style=\"color: #606060;\">  29:<\/span>             });<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum30\" style=\"color: #606060;\">  30:<\/span>             modelBuilder.Entity&lt;Authors&gt;().HasKey(e =&gt; <span style=\"color: #0000ff;\">new<\/span> { e.AuthorID});<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum31\" style=\"color: #606060;\">  31:<\/span><\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum32\" style=\"color: #606060;\">  32:<\/span>             modelBuilder.Entity&lt;Books&gt;(entity =&gt;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum33\" style=\"color: #606060;\">  33:<\/span>             {<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum34\" style=\"color: #606060;\">  34:<\/span>                 entity.Property(e =&gt; e.ISBN).HasColumnName(<span style=\"color: #006080;\">\"isbn\"<\/span>);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum35\" style=\"color: #606060;\">  35:<\/span>                 entity.Property(e =&gt; e.CategoryID).HasColumnName(<span style=\"color: #006080;\">\"category_id\"<\/span>);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum36\" style=\"color: #606060;\">  36:<\/span>                 entity.Property(e =&gt; e.Title).HasColumnName(<span style=\"color: #006080;\">\"title\"<\/span>);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum37\" style=\"color: #606060;\">  37:<\/span>                 entity.Property(e =&gt; e.Photo).HasColumnName(<span style=\"color: #006080;\">\"photo\"<\/span>);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum38\" style=\"color: #606060;\">  38:<\/span>                 entity.Property(e =&gt; e.PublishDate).HasColumnName(<span style=\"color: #006080;\">\"publish_date\"<\/span>);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum39\" style=\"color: #606060;\">  39:<\/span>                 entity.Property(e =&gt; e.Price).HasColumnName(<span style=\"color: #006080;\">\"price\"<\/span>);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum40\" style=\"color: #606060;\">  40:<\/span>                 entity.Property(e =&gt; e.Quantity).HasColumnName(<span style=\"color: #006080;\">\"qty\"<\/span>);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum41\" style=\"color: #606060;\">  41:<\/span>             });<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum42\" style=\"color: #606060;\">  42:<\/span>             modelBuilder.Entity&lt;Books&gt;().HasKey(e =&gt; <span style=\"color: #0000ff;\">new<\/span> { e.ISBN});<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum43\" style=\"color: #606060;\">  43:<\/span><\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum44\" style=\"color: #606060;\">  44:<\/span>             modelBuilder.Entity&lt;BooksAuthors&gt;(entity =&gt;<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum45\" style=\"color: #606060;\">  45:<\/span>             {<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum46\" style=\"color: #606060;\">  46:<\/span>                 entity.Property(e =&gt; e.ISBN).HasColumnName(<span style=\"color: #006080;\">\"isbn\"<\/span>);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum47\" style=\"color: #606060;\">  47:<\/span>                 entity.Property(e =&gt; e.AuthorID).HasColumnName(<span style=\"color: #006080;\">\"author_id\"<\/span>);<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum48\" style=\"color: #606060;\">  48:<\/span>             });<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum49\" style=\"color: #606060;\">  49:<\/span>             modelBuilder.Entity&lt;BooksAuthors&gt;().HasKey(e =&gt; <span style=\"color: #0000ff;\">new<\/span> { e.ISBN, e. AuthorID });<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum50\" style=\"color: #606060;\">  50:<\/span>         }<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum51\" style=\"color: #606060;\">  51:<\/span>         <span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">virtual<\/span> DbSet&lt;Categories&gt; Categories { get; set; }<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum52\" style=\"color: #606060;\">  52:<\/span>         <span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">virtual<\/span> DbSet&lt;Authors&gt; Authors { get; set; }<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum53\" style=\"color: #606060;\">  53:<\/span>         <span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">virtual<\/span> DbSet&lt;Books&gt; Books { get; set; }<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum54\" style=\"color: #606060;\">  54:<\/span>         <span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">virtual<\/span> DbSet&lt;BooksAuthors&gt; BooksAuthors { get; set; }<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: white; border-style: none; padding: 0px;\"><span id=\"lnum55\" style=\"color: #606060;\">  55:<\/span>     }<\/pre>\n<p><!--CRLF--><\/p>\n<pre style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span id=\"lnum56\" style=\"color: #606060;\">  56:<\/span> }<\/pre>\n<p><!--CRLF--><\/p>\n<\/div>\n<\/div>\n<p>Pada baris ke-51 sampai dengan baris ke-54 dapat dilihat bagaimana cara memetakan class dengan tabel.\u00a0 Berikut adalah sintaks dan penjelasan dari keempat baris tersebut.<\/p>\n<div id=\"codeSnippetWrapper\" style=\"font-size: 8pt; overflow: auto; cursor: text; font-family: 'Courier New', courier, monospace; width: 97.5%; direction: ltr; text-align: left; margin: 20px 0px 10px; line-height: 12pt; max-height: 200px; background-color: #f4f4f4; border: silver 1px solid; padding: 4px;\">\n<pre id=\"codeSnippet\" style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\"><span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">virtual<\/span> DbSet&lt;NAMA_CLASS_ENTITY&gt; NAMA_TABLE { get; set; }<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<p>Cara lain untuk memetakan class entity dengan table juga dapat dilakukan dengan penulisan kode di dalam method OnModelCreating dengan sintaks sebagai berikut.<\/p>\n<div id=\"codeSnippetWrapper\" style=\"font-size: 8pt; overflow: auto; cursor: text; font-family: 'Courier New', courier, monospace; width: 97.5%; direction: ltr; text-align: left; margin: 20px 0px 10px; line-height: 12pt; max-height: 200px; background-color: #f4f4f4; border: silver 1px solid; padding: 4px;\">\n<pre id=\"codeSnippet\" style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\">modelBuilder.Entity&lt;NAMA_CLASS_ENTITY&gt;().ToTable(<span style=\"color: #006080;\">\"NAMA_TABLE\"<\/span>);<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<p>Sehingga untuk melakukan mapping class BooksAuthors dengan table books_authors dapat dilakukan dengan cara berikut.<\/p>\n<div id=\"codeSnippetWrapper\" style=\"font-size: 8pt; overflow: auto; cursor: text; font-family: 'Courier New', courier, monospace; width: 97.5%; direction: ltr; text-align: left; margin: 20px 0px 10px; line-height: 12pt; max-height: 200px; background-color: #f4f4f4; border: silver 1px solid; padding: 4px;\">\n<pre id=\"codeSnippet\" style=\"font-size: 8pt; overflow: visible; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;\">modelBuilder.Entity&lt;BooksAuthors&gt;().ToTable(<span style=\"color: #006080;\">\"books_authors\"<\/span>);<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<p>Kemudian untuk mapping property-property dari class Categories ke atribut-atribut table categories dapat dilihat pada baris ke-19 dan ke-20.\u00a0 Sedangkan untuk menentukan property mana yang akan menjadi primary key dapat dilihat pada baris ke-22.\u00a0 Kemudian untuk kasus ketika table memiliki dua primary key seperti tabel books_authors, maka dapat dilihat pada baris ke-49 sebagai cara menentukan lebih dari satu property pada class sebagai primary key.<\/p>\n<p>{<strong><em>Kesimpulan<\/em><\/strong>}<\/p>\n<p>Kedua cara di atas dapat digunakan sekaligus dan saling melengkapi.\u00a0 Tetapi menurut saran saya, agar lebih baik menggunakan Fluent API secara penuh, karena fitur-fitur yang diberikan telah lengkap.\u00a0 Dan hal itu juga membuat isi class entity lebih bersih karena konfigurasi dilakukan pada file terpisah dan terpusat, yaitu pada file class data context.<\/p>\n<p>Selamat mencoba, semoga bermanfaat.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Entity Framework adalah framework untuk mempermudah mengakses database. Framework ini awalnya dibangun sebagai bagian dari .NET framework yang hanya dapat digunakan pada platform Microsoft. Tetapi dengan dikembangkannya .NET Core yang bersifat multiplatform, maka Entity Framework Core juga dapat digunakan pada&hellip;<\/p>\n","protected":false},"author":1,"featured_media":3260,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":true,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[6],"tags":[68,160],"class_list":["post-3261","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-softwaredev","tag-asp-net","tag-asp-net-core"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"http:\/\/www.rezafaisal.net\/wp-content\/uploads\/2017\/02\/01_thumb-6.jpg","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p1sNAL-QB","_links":{"self":[{"href":"http:\/\/www.rezafaisal.net\/index.php?rest_route=\/wp\/v2\/posts\/3261","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.rezafaisal.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.rezafaisal.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.rezafaisal.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.rezafaisal.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3261"}],"version-history":[{"count":2,"href":"http:\/\/www.rezafaisal.net\/index.php?rest_route=\/wp\/v2\/posts\/3261\/revisions"}],"predecessor-version":[{"id":3263,"href":"http:\/\/www.rezafaisal.net\/index.php?rest_route=\/wp\/v2\/posts\/3261\/revisions\/3263"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/www.rezafaisal.net\/index.php?rest_route=\/wp\/v2\/media\/3260"}],"wp:attachment":[{"href":"http:\/\/www.rezafaisal.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3261"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.rezafaisal.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3261"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.rezafaisal.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3261"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}