Skip to content

Commit

Permalink
Fluent API
Browse files Browse the repository at this point in the history
  • Loading branch information
XuanThuLab committed Aug 25, 2020
1 parent a4a4257 commit 8e63178
Show file tree
Hide file tree
Showing 10 changed files with 348 additions and 0 deletions.
Binary file removed .DS_Store
Binary file not shown.
27 changes: 27 additions & 0 deletions EF/ef03/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/bin/Debug/netcoreapp3.1/ef03.dll",
"args": [],
"cwd": "${workspaceFolder}",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
"stopAtEntry": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
}
]
}
42 changes: 42 additions & 0 deletions EF/ef03/.vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/ef03.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/ef03.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"${workspaceFolder}/ef03.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
}
]
}
23 changes: 23 additions & 0 deletions EF/ef03/Model/Category.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace ef03.Model
{
[Table("Category")]
public class Category
{
[Key]
public int CategoryId {set; get;}

[StringLength(100)]
public string Name {set; get;}

[Column(TypeName="ntext")]
public string Description {set; get;}

// Các sản phẩm thuộc về Category - Đây là điều hướng dạng Collection Navigation (tập hợp)
public virtual List<Product> products {set; get;}

}
}
36 changes: 36 additions & 0 deletions EF/ef03/Model/Product.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace ef03.Model
{
[Table("Products")] // Ánh xạ bảng Product
public class Product
{
[Key] // Là Primary key
public int ProductId {set; get;}

[Required] // Cột trong DB, Not Null
[StringLength(50)] // nvarchar(50)
public string Name {set; get;}

[Column(TypeName="Money")] // cột kiểu Money trong SQL Server (tương ứng decimal trong Model C#)
public decimal Price {set; get;}

// hoặc thêm [Required] khi int?
public int CategoryId {set; get;} // Thuộc tính sẽ thiết lập là FK

[ForeignKey("CategoryId")]
public virtual Category Category {set; get;} // Sinh FK (CategoryID ~ Cateogry.CategoryID) ràng buộc đến PK key của Category


public int? CategorySecondId;
[ForeignKey("CategorySecondId")]
[InverseProperty("products")]
public virtual Category SecondCategory {set; get;}


public int? UserPostId {set; get;} // Lưu thông tin người Post sản phẩm
public virtual User UserPost {set; get;} // Tham chiếu User

}
}
154 changes: 154 additions & 0 deletions EF/ef03/Model/ShopContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace ef03.Model {
public class ShopContext : DbContext {
protected string connect_str = @"Data Source=localhost,1433;
Initial Catalog=shopdata;
User ID=SA;Password=Password123";
public DbSet<Product> products { set; get; } // bảng Products
public DbSet<Category> categories { set; get; } // bảng Category

public DbSet<User> users {set; get;} // bảng User

protected override void OnConfiguring (DbContextOptionsBuilder optionsBuilder) {
base.OnConfiguring (optionsBuilder);

// Tạo ILoggerFactory
ILoggerFactory loggerFactory = LoggerFactory.Create (builder => builder.AddConsole ());

optionsBuilder.UseSqlServer (connect_str) // thiết lập làm việc với SqlServer
.UseLoggerFactory (loggerFactory) // thiết lập logging
.UseLazyLoadingProxies ();

}

// Tạo database
public async Task CreateDatabase () {
String databasename = Database.GetDbConnection ().Database;

Console.WriteLine ("Tạo " + databasename);
bool result = await Database.EnsureCreatedAsync ();
string resultstring = result ? "tạo thành công" : "đã có trước đó";
Console.WriteLine ($"CSDL {databasename} : {resultstring}");
}

// Xóa Database
public async Task DeleteDatabase () {
String databasename = Database.GetDbConnection ().Database;
// Console.Write($"Có chắc chắn xóa {databasename} (y) ? ");
// string input = Console.ReadLine();

// // Hỏi lại cho chắc
// //if (input.ToLower() == "y")
{
bool deleted = await Database.EnsureDeletedAsync ();
string deletionInfo = deleted ? "đã xóa" : "không xóa được";
Console.WriteLine ($"{databasename} {deletionInfo}");
}
}

// Chèn dữ liệu mẫu
public async Task InsertSampleData () {
// Thêm 2 danh mục vào Category
var cate1 = new Category () { Name = "Cate1", Description = "Description1" };
var cate2 = new Category () { Name = "Cate2", Description = "Description2" };
await AddRangeAsync (cate1, cate2);
await SaveChangesAsync ();

// Thêm 5 sản phẩm vào Products
await AddRangeAsync (
new Product () { Name = "Sản phẩm 1", Price = 12, Category = cate2 },
new Product () { Name = "Sản phẩm 2", Price = 11, Category = cate2 },
new Product () { Name = "Sản phẩm 3", Price = 33, Category = cate2 },
new Product () { Name = "Sản phẩm 4(1)", Price = 323, Category = cate1 },
new Product () { Name = "Sản phẩm 5(1)", Price = 333, Category = cate1 }

);
await SaveChangesAsync ();

// Các sản phầm chèn vào
foreach (var item in products) {
StringBuilder stringBuilder = new StringBuilder ();
stringBuilder.Append ($"ID: {item.ProductId}");
stringBuilder.Append ($"tên: {item.Name}");
stringBuilder.Append ($"Danh mục {item.CategoryId}({item.Category.Name})");
Console.WriteLine (stringBuilder);

}

}

// Truy vấn lấy về sản phẩm theo ID
public async Task<Product> FindProduct (int id) {

var p = await (from c in products where c.ProductId == id select c).FirstOrDefaultAsync ();
await Entry (p) // lấy DbEntityEntry liên quan đến p
.Reference (x => x.Category) // lấy tham chiếu, liên quan đến thuộc tính Category
.LoadAsync (); // nạp thuộc tính từ DB
return p;
}
// Truy vấn lấy về Category theo ID
public async Task<Category> FindCategory (int id) {

var cate = await (from c in categories where c.CategoryId == id select c).FirstOrDefaultAsync ();
await Entry (cate) // lấy DbEntityEntry liên quan đến p
.Collection (cc => cc.products) // lấy thuộc tính tập hợp, danh sách các sản phẩm
.LoadAsync (); // nạp thuộc tính từ DB
return cate;
}

// Phương thức này thi hành khi EnsureCreatedAsync chạy, tại đây gọi các Fluent API mong muốn
override protected void OnModelCreating (ModelBuilder modelBuilder) {

base.OnModelCreating (modelBuilder);

modelBuilder.Entity<User>(entity => {
// Thiết lập cho bảng
entity
.ToTable("User") // Tùy chọn tên của bảng là User (mặc định user)
.HasComment("Đây là bảng người dùng") // Dòng chú thichs
.HasKey(e => e.UserId); // Thiết lập Primary key là UserId
// Thiết lập cho cột UserID
entity.Property(e => e.UserId)
.UseIdentityColumn(1,1);
// Thiết lập cho cột UserName
entity.Property(e => e.UserName)
.HasColumnName("user_name") //Tùy chọn đặt lại tên cột user_name (mặc định UserName)
//.HasColumnType("varchar(20)")
.HasDefaultValue("Không tên") // Giá trị mặc định
.HasMaxLength(20); // Độ dài của trường dữ liệu 20
entity.HasIndex(p => p.UserName) // Đánh chỉ mục UserName (user_name)
.IsUnique(true); // Unique
});

// Bảng Products

modelBuilder.Entity<Product>(entity => {
// Thiết lập cho bảng Product
entity.HasOne(e => e.UserPost) // Chỉ ra Entity là phía một (bảng User)
.WithMany(user => user.ProductsPost) // Chỉ ra Collection tập Product lưu ở phía một
.HasForeignKey("UserPostId") // Chỉ ra tên FK nếu muốn
.OnDelete(DeleteBehavior.SetNull) // Ứng xử khi User bị xóa (Hoặc chọn DeleteBehavior.Cascade)
.HasConstraintName("FK_Products_user_1234"); // Tự đặt tên Constrain (dàng buốc)
});



}

}
}
15 changes: 15 additions & 0 deletions EF/ef03/Model/User.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using ef03.Model;

namespace ef03.Model
{
public class User
{
public int UserId {set; get;}

public string UserName {set; get;}

public virtual List<Product> ProductsPost {set; get;}
}
}
27 changes: 27 additions & 0 deletions EF/ef03/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;
using System.Threading.Tasks;
using ef03.Model;

namespace ef03
{
class Program
{

static async Task Main(string[] args)
{
ShopContext context = new ShopContext();

await context.DeleteDatabase(); // xóa database: shopdata nếu tồn tại
await context.CreateDatabase(); // tạo lại database: shopdata

context.Add(new User {UserName = "xuanthulab"});

// context.Add(new Category {Name = "Điện tử"});
// context.Add(new Product { Name = "Iphone", CategoryId = 1, UserPostId = 1});
context.SaveChanges();



}
}
}
22 changes: 22 additions & 0 deletions EF/ef03/ef03.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.7" />

<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="3.1.7" />

<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.3" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.7" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.7" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.7" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.2" />
</ItemGroup>

</Project>
2 changes: 2 additions & 0 deletions EF/ef03/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# (EF Core) Tạo quan hệ trong Entity Framework với Fluent API C# CSharp
https://xuanthulab.net/ef-core-tao-quan-he-trong-entity-framework-voi-fluent-api-c-csharp.html

0 comments on commit 8e63178

Please sign in to comment.