Thứ Sáu, 10 tháng 3, 2017

Hiện chi tiết ngoại lệ trong Entity Framework

Nhiều bạn khi làm việc với Entity Framework trên .NET thường gặp phải lỗi quen thuộc "System.Data.Entity.Validation.DbEntityValidationException: Validation failed for one or more entities. See 'EntityValidationErrors' property for more details." phải không nào? 😍


Thông báo ngoại lệ huyền thoại khi làm việc với EF :))


Nội dung của đoạn báo ngoại lệ này có ý nghĩa rằng bạn đã vi phạm 1 ràng buộc nào đó trên 1 hoặc nhiều entities. Một đoạn thông báo khá mơ hồ như vậy khiến nhiều bạn phải vất vả ngồi dò lại code và dò cả các ràng buộc bạn đặt trong cơ sở dữ liệu. Nếu bạn dùng khối catch chung chung để bắt ngoại lệ thì cũng nhận được thông báo như vậy.

Để giải quyết vấn đề này mình sẽ hướng dẫn bạn sử dụng khối try catch sau đây để có thể nhìn thấy rõ ngoại lệ mà bạn gặp phải như là định dạng ngày tháng không hợp lệ, khóa chính bị trùng, độ dài ký tự vượt quá độ dài tối đa, ... Nội dung đoạn try catch này như sau:

        try
        {
            // code của bạn
        }
        catch (DbEntityValidationException ex)
        {
            // Retrieve the error messages as a list of strings.
            var errorMessages = ex.EntityValidationErrors
                    .SelectMany(x => x.ValidationErrors)
                    .Select(x => x.ErrorMessage);
    
            // Join the list to a single string.
            var fullErrorMessage = string.Join("; ", errorMessages);
    
            // Combine the original exception message with the new one.
            var exceptionMessage = string.Concat(ex.Message, " The validation errors are: ", fullErrorMessage);
    
            // Throw a new DbEntityValidationException with the improved exception message.
            throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
        }

Ý nghĩa đoạn lệnh này như sau. Mình dùng khối catch (DbEntityValidationException ex) để bắt những ngoại lệ liên quan đến ràng buộc trong các entity class, sau đó trong lệnh catch mình sử dụng đối tượng ex và dùng thuộc tính EntityValidationErrors để lấy ra tất cả những lỗi và gán những thông báo lỗi qua 1 biến mảng errorMessages. Sau đó mình đổi mảng thành chuỗi với quy định mỗi phần tử trong mảng sẽ ngăn nhau bởi dấu ; thông qua phương thức string.Join(). Tiếp nữa mình kết hợp thông báo ngoại lệ ban đầu và thông qua ngoại lệ mới và gán qua biến exceptionMessage. Cuối cùng mình dùng lệnh throw để ném ra ngoại lệ cùng 1 thông báo chi tiết về lỗi bạn đang gặp phải.

Công việc còn lại của bạn khi biết rõ ràng lỗi là dễ dàng và đỡ tốn thời gian hơn nhiều so với việc đi dò từng đoạn lệnh và debug đi debug lại. Mong rằng bài viết sẽ giúp các bạn thật nhiều trong các dự án sắp tới 😃.


EmoticonEmoticon