Saturday, May 25, 2019

Tuyệt chiêu tránh khỏi sự chậm chạm của Entity Framework




Nhìn chung mà nói, tôi chả lo lắng gì nhiều về câu lệnh LINQ của tôi khi làm việc với Entity Framework. Tôi luôn luôn nói với khách hàng của mình rằng nếu họ muốn tăng tốc độ truy cập dữ liệu họ nên xem lại cách thiết kế cơ sở dữ liệu, đặc biệt là cách sử dụng index.

Nhưng vẫn có một ngoại lệ cho quy tắc này: nếu bạn có một câu lệnh so sánh một cột char hoặc một cột varchar, bạn đã có thể làm chậm đi câu lệnh LINQ của mình. Vấn đề là Entity Framework coi rằng dữ liệu chuỗi của bạn là kiểu unicode (nchar hoặc nvarchar) nên nếu mà bạn vướng phải tường hợp này thì một vài sự chuyển đổi kiểu dữ liệu sẽ khiến cho câu lệnh của bạn chạy chậm chạm đi

Câu lệnh LINQ
Var res = From cust In db.Customers
            Where cust.Name = "Vogel"
           Select cust

Sẽ trở thành
Select *
From Customers
Where Name = N'Vogel'

Bởi vì Entity Framework mặc định rằng cột dữ liệu của bạn là kiểu Unicode, nó nối thêm N đằng trước chuỗi truy vấn của bạn rồi cố gắng so sánh một chuỗi Unicode (biến bạn truyền vào) với một chuỗi non-Unicode (cột dữ liệu của bạn)

Giải pháp là chỉ cho Entity Framework biết là cột của bạn là cột char hoặc varchar bằng cách thiết lập thuộc thính Column với TypeName là varchar

<Column(TypeName="varchar")>
Public Property Name As String


Một bài viết dài hơn mô tả cụ thể trường hợp dính phải vụ này được đăng ở blog post của Brian Sullivan và cách anh ấy xử lý vấn đề.


7 nguyên tắc thiết kế REST API


URIs
REST API sử dụng URI để đánh địa chỉ tài nguyên.

Người thiết kế rest api nên tạo ra những URI mang tới những thông tin mô tả về tài nguyên của REST API cho khách hàng.

theo tiêu chuẩn RFC 3986, cú pháp URL :
URI = scheme://authority/path[?query][#fragment]

Quy tắc #1: Dấu gạch chéo kết thúc không nên được đặt vào trong URI

Đây là một quy tắc quan trọng, dấu gạch chéo (/) được thêm vào đằng sau URI không có ý nghĩa và dễ gây nhầm lẫn. REST API không nên cho dấu này khi cung cấp cho khách hàng
2 URI sau đây là không tương đương
Nhìn thì giống nhau nhưng 2 URI khác nhau sẽ dẫn tới 2 tài nguyên khác nhau.
Ta cũng có thể lựa chọn giải pháp là moved permanently rest api thứ nhất về api thứ 2


Quy tắc #2: Dấu gạch chéo phải được sử dụng để biểu thị mối quan hệ phân cấp

Dấu gạch chéo được. sử dụng trong phân chia đường dẫn của URI để biểu thị quan hệ phân cấp trong tài nguyên
Ví dụ:


Quy tắc #3: Dấu gạch ngang nên được sử dụng để cải thiện khả năng có thể đọc được của URI

Để tạo cho URI của bạn dễ dàng cho mọi người có thể đọc và hiểu được, sử dụng dấu gạch ngang (-) trong những đoạn tên dài. Bất cứ chỗ nào bạn sử dụng giấu cách hoặc dấu gạch ngang trong ngữ văn thông thường thì bạn nên sử dụng dấu gạch ngang trong URI


Quy tắc #4: Dấu gạch dưới không nên sử dụng trong URI

Những ứng dụng như trình duyệt, trình soạn thảo văn bản thường gạch chân URI để ra dấu hiệu rằng chúng có thể click vào được. Phụ thuộc vào font của ứng dụng, dấu gạch chân (_) có thể bị ẩn đi mất khi font chữ bị gạch dưới
Để tránh khỏi sự nhầm lẫn này, sử dụng dấu gạch ngang thay vì dấu gạch chân

Quy tắc #5: Kí tự viết thường nên được sử dụng trong URI

để thuận tiện, kí tự viết thường thường được ưa dùng hơn kí tự viết hoa bởi 1 số vấn đề. RFC 3986 định nghĩa URI là phân biệt chữ hoa, chững thường ngoại trừ scheme và host component
Ví dụ:
Đặc tả định dạng URI RFC 3986 định danh 2 URI này là giống nhau

URI này không giống 2 URI đầu vì thế dễ gây ra nhầm lẫn ko cần thiết

Quy tắc #6: Phần mở rộng của file không nên đưa vào trong URI

Trên web, dấu chấm (.) thường được sử dụng để phân cách tên file và phần mở rộng.
Một REST API thì không nên bao gồm phần này . Thay vào đó chúng nên dựa vào kiểu dữ liệu trên Content-Type header để xác định khi xử lý nội dung dữ liệu


phần mở rộng của file không được được biểu thị ở trên mà ở client nên cung cấp một cơ chế lựa chọn vào phần Accept header cuả request

Quy tắc #7: Nên đặt tên endpoint là số ít hay số nhiều?

Một quy tắc đơn giản được áp dụng là, hãy giữ cho URI có định dạng phù hợp của nó, và nên là số nhiều
Ví dụ: /students và /students/12345
Với 1 học sinh có nhiều khóa học thì logic của endpoint này sẽ là:
/students/12345/courses


Nguồn: https://dzone.com/articles/7-rules-for-rest-api-uri-design-1

Friday, March 15, 2019

Oracle 18c có gì mới?

1. JSON


2. Table Function


3. Group by


4. Listagg mà đếch cần within group (order by ...)


5. Chuẩn SQL mới


6. Chả biết viết gì nữa

Tuesday, March 12, 2019

10 thủ thuật tối ưu câu lệnh SQL trên tất cả các hệ quản trị cơ sở dữ liệu quan hệ

-- các bạn đón đọc vào tối 14/3 nhé --

Cách thiết kế Web API ASP.NET Self Host - tự chạy ko cần Web server IIS

Đã là lập trình web thì ta đều biết rằng khi code xong web thì ta phải đưa nó vào 1 web server để nó chạy được.

Khi code web asp.net thì ta chỉ có 1 lựa chọn web server duy nhất là IIS

Nhưng mà công nghệ ngày một phát triển, các lập trình viên đã sáng chế ra một phương thức mà web asp.net giờ đây không phải host trên IIS nữa. Tên của sáng chế đó là OWIN - Open Web Interface for .NET

Theo định nghĩa ngắn gọn của các chuyên gia thì :
OWIN is a open source specification that is not defined by microsoft and is not an actual implementation
OWIN là một đặc tả mã nguồn mở không phải hàng chính hãng Microsoft cơ mà đã được đưa vào thực tế ngon ngẻ rồi nha

Vậy túm lại thì OWIN chỉ là một đặc tả thôi, nó mới là lý thuyết trên giấy. Còn đây mà là hero nè : Katana

Katana là tên một dự án mã nguồn mở xây dựng các tập công cụ theo đặc tả được mô tả trong OWIN. 

Chúng ta sẽ dần dần tìm hiểu các công cụ này bằng một project web api demo nhé

Bước đầu tiên là ta cần install 2 package sau bằng cách gõ lệnh trên Package Manager

PM> Install-Package Microsoft.Owin.SelfHost
PM> Install-Package Microsoft.AspNet.WebApi.OwinSelfHost


Sau đó thì ta tạo 1 class cấu hình với tên là Startup để cấu hình router cho web api như bình thường

using System.Web.Http;
using Owin;

namespace AspNetSelfHostDemo
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Configure Web API for self-host. 
            var config = new HttpConfiguration();
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            app.UseWebApi(config); 
        }
    }
}

Sau đó ta tạo một controller web api như bình thường 

using System.Collections.Generic;
using System.Web.Http;

namespace AspNetSelfHostDemo
{
    public class DemoController : ApiController
    {
        // GET api/demo 
        public IEnumerable<string> Get()
        {
            return new string[] { "Hello", "World" };
        }

        // GET api/demo/5 
        public string Get(int id)
        {
            return "Hello, World!";
        }

        // POST api/demo 
        public void Post([FromBody]string value)
        {
        }

        // PUT api/demo/5 
        public void Put(int id, [FromBody]string value)
        {
        }

        // DELETE api/demo/5 
        public void Delete(int id)
        {
        }
    } 
}

Và bước cuối cùng đơn giản không kém đây, ta tạo một class để khởi động (class này gọi ra đặc tả WebApp.Start trong Katana project đó) nhồi vào Start là tên class cấu hình <Startup> với tham số là thông tin host và port tự đặt để chạy chương trình
using System;
using Microsoft.Owin.Hosting;

namespace AspNetSelfHostDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            using (WebApp.Start<Startup>("http://localhost:8080"))
            {
                Console.WriteLine("Web Server is running.");
                Console.WriteLine("Press any key to quit.");
                Console.ReadLine();
            }
        }
    }
}

Thật là đơn giản phải không nào, ta chạy chương trình và bật postman lên thưởng thức thành quả thôi nào
http://localhost:8080/api/demo

Chúc các bạn một ngày nghiên cứu thật vui vẻ

Cách lập trình module Web API trong DotnetNuke

Kể từ DNN ver7 trở lên thì framework này đã hỗ trợ tạo web api một cách rất đơn giản

Điều kiện cần là trong thư mục bin của framework có các dll sau đây
  • DotNetNuke.dll
  • DotNetNuke.Web.dll
  • System.Net.Http.dll
  • System.Net.Http.Formatting.dll
  • System.Web.Http.dll
Bước đầu tiên là tạo một module mới, cách tạo module mới thì mình không nêu ở đây

Tiếp theo là tạo một class RouterMapper để làm nhiệm vụ router cho api trỏ vào đúng hàm mình viết trong module
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using DotNetNuke.Web.Api;

namespace MyModuleName.WebAPI {
    public class RouterMapper : IServiceRouteMapper {
        public void RegisterRoutes(IMapRoute mapRouteManager) {
            mapRouteManager.MapHttpRoute("MyModuleName.WebAPI", "default", "{controller}/{action}", new[] { "MyModuleName.WebAPI" });
        }
    }
}

ở trên bạn đã khai báo folder hệ thống chứa code, sau đó là tên controller (class xử lý) và action là tên phương thức (method xử lý), cái cuối cùng sau new[] các bạn để tên namespace của module đó nha

sau khi tạo router xong thì api sẽ ở địa chỉ này
/desktopmodules/MyModuleName.WebAPI/api/{controller}/{action}

Bây giờ thì tạo controller với action thôi

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Http;
using DotNetNuke.Web.Api;
using System.Net.Http;
using System.Net;
using System.Text;

namespace MyModuleName.WebAPI {
    public class HelloWorldController : DnnApiController {
        [HttpPost]
        public HttpResponseMessage PostMyName([FromBody] yourName) {
            try {
                return Request.CreateResponse(HttpStatusCode.OK, "Hello World " + yourName);
            } catch (Exception ex) {
                return Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message);
            }
        }
  
 [HttpGet]
        public HttpResponseMessage GetMyName([FromBody] yourName) {
            try {
                return Request.CreateResponse(HttpStatusCode.OK, "Hello World " + yourName);
            } catch (Exception ex) {
                return Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message);
            }
        }
  
 [HttpPost]
 [DnnAuthorize]
        public HttpResponseMessage PostMyName([FromBody] PersonInfo objPerson) {
            try {
                return Request.CreateResponse(HttpStatusCode.OK, "Hello World " + objPerson.FirstName + " " + objPerson.LastName);
            } catch (Exception ex) {
                return Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message);
            }
        }
    } }

Ở trên ta vừa tạo Controller có tên là HelloWorld (HelloWorldController) kế thừa từ  DnnApiController

Có 2 attribute mà ta cần chú là là [HttpPost] và [HttpGet] là để khai báo method Post và Get của giao thức http, trong phần parameter nếu truyền dữ liệu vào body thì ta thêm [FromBody] vào trước

Reponse thì ta có thể tự thiết kế để trả về object kiểu gì mà ta muốn

Đơn giản vậy thôi nha, vừa rồi mình đã chỉ cho các bạn thiết kế web api
/desktopmodules/MyModuleName.WebAPI/api/HelloWorld/GetMyName 
trong DotnetNuke nha, chúc các bạn một ngày nghiên cứu công nghệ vui vẻ

Monday, March 4, 2019

Một số lưu ý khi cài đặt Oracle 18c trên Windows


Ngoài các lưu ý cần để ý khi cài Oracle như trong bài viết một số lưu ý khi cài đặt oracle 12c thì khi cài Oracle 18c các anh em cần chú ý một số điều sau


1. Nhớ là máy tính phải đạt tối thiểu 8GB Ram đó nha, ko là lại mếu như ai


2. Cài trên windows 7 cứ đến chỗ này là fail, các bạn nhớ xài windows bản cao hơn nha, ko là hẹo đấy
P/s: có một số anh em thiện lành nói rằng chỉ cần ấn cái nút Retry ở trên cái logo đỏ nè nè là được, các anh em thử xem sao nha

Sau khi lên windows 10 thì mình đã cài thành công

Oracle 18c cài lâu lắm, các bạn nhớ ngồi chờ kiên nhẫn nha
Cài đặt thành công rồi nè, hehe


Đó ! lưu ý chỉ có vậy thôi, nhớ đọc thêm bài một số lưu ý khi cài đặt oracle 12c để lưu ý sâu sắc hơn nữa nha.


Chúc anh em 1 ngày vọc vạch vui vẻ !

Sunday, March 3, 2019

Sử dụng PLJSON để thao tác dữ liệu JSON trong Oracle


Có một thư viện là PLJSON được phát triển rất lâu rồi để xử lý chuỗi JSON cho Oracle, nó cũng dễ dùng thôi, cài đặt cũng dễ nhé, chỉ cần chạy script install của nó 1 phát là được

Anh em vào trang này down cả bộ script cài đặt của nó về nè https://github.com/pljson/pljson
down về xong giải nén ra có 1 đống file luôn anh em cứ kệ cha nó nha ko cần care, hehe

Anh em chỉ cần mở sql developer lên hay bất cứ chương trình chạy sql nào của oracle cũng được, open file install.sql chạy nó là ô kê

Chạy mất mấy giây là xong nha, nhanh lắm, tuy nhiên một vài người anh em sẽ gặp lỗi khi cài đặt cái này, cái đó thì anh em nào thắc mắc qua sẽ giải đáp cho các anh em nha, qua có tất cả các câu trả lời mà anh em cần nha, nhưng mà các anh em phải hỏi mới đc

Về cơ bản thì lib pljson này có 2 đối tượng chính:

- JSON: đại diện cho 1 element {}

- JSON_LIST: đại diện cho 1 mảng element []

Còn 1 vài đối tượng nữa cơ mà qua chỉ cho các anh em dần dần nha, các anh em đừng vội vàng quá, hỏng hết cả bánh kẹo đó


Qua bắt đầu nha, trước hết là các chiêu thức cơ bản nè, anh em tập trung nè

* Cách khai báo biến

declare
obj json;
obj2 json_list;

* Để biến 1 chuỗi thành đối tượng json thì đơn giản lắm nha các anh em

obj := json('{"a": true }');
obj2 := json_list('[1,2,3,[3, []]]');


* Để build đối tượng json rồi sau đó out ra chuỗi
obj := json(); --an empty structure
obj.put('A', 'a little string');
obj.put('B', 123456789);
obj.put('C', true);
obj.put('D', false);
obj.put('F', json_value.makenull);
obj.print;

json list thì cũng tương tự nha
obj2 := json_list(); --an empty structure
obj2.append('a little string');
obj2.append(123456789);
obj2.append(true);
obj2.append(false);
obj2.append(json_value);
obj2.print;

* Build ra đối tượng rồi thì dễ dàng chỉnh sửa đối tượng nha, ví dụ như qua có thể xóa 1 phần tử của json khi mà phần tử thêm vào làm qua thấy ngứa mắt nha
obj.remove(4);
obj.remove_first;
obj.remove_last;

* Build xong đối tượng json là obj rồi thì ta có thể lấy các value trong chuỗi json ra bằng các get key của nó
obj.get('A');

các anh em thiện lành nhớ là get như thế này thì nó ra kết quả là 1 đối tượng json_value nha, các anh em dùng thuộc tính .str để lấy ra string 
so_ngoc_trinh:=obj.get('A').str;

Đó, hôm nay qua chỉ nói thế này thôi cho anh em thiện lành ngấm dần dần, hôm nào qua lại nói tiếp, các anh em chú ý là qua có mọi câu trả lời anh em cần nha. Vậy nên các anh em cứ hỏi, có thời gian qua sẽ trả lời nha.

Chúc anh em làm tốt và nhớ theo dõi các bài viết tiếp theo nha!

Một số lưu ý khi cài đặt Oracle 12c trên Windows


1. Nhớ chạy setup với quyền admin để tránh sự cố ko đáng có nha



2. Không cần nhập email cũng đc nha, cứ nhấn ok next để qua thôi



3. Tạo một tài khoản windows cho riêng oracle



4. Đường dẫn cài đặt oracle ko được để khoảng trắng nha, nếu có thì xóa đi cài mới ok đc





5. Đăng nhập thì chọn service name nhé, ko cứ chọn SID thì lại bảo sao nó ơ rô



6. Dữ liệu db là các file được lưu trong thư mục oradata nha, nhiều file lắm nhưng file nào cũng quan trọng hết, nên đừng có nghịch dại mà xóa đi





6. Sử dụng luôn sql developer được cài cùng với oracle nha, cây nhà lá vườn cứ xài tự nhiên




Cài xong hết rồi đấy, giờ là chạy phè phè thôi

Tuyệt chiêu tránh khỏi sự chậm chạm của Entity Framework

Nhìn chung mà nói, tôi chả lo lắng gì nhiều về câu lệnh LINQ của tôi khi làm việc với Entity Fra...