Nhận loại lỗi chính xác từ DbValidationException


184

Tôi gặp tình huống tôi đang khởi tạo mô hình của mình trong DatabaseInitializer () cho EF 4.1 và gặp lỗi khó chịu này "Validation failed for one or more entities. See 'EntityValidationErrors' property for more details."Vì vậy, tôi đi đến EntityValidationErrors này và có một trường {System.Data.Entity.Validation.DbEntityValidationResult}không cung cấp cho tôi thông tin nào về trường nào không thể khởi tạo . Có cách nào để có thêm thông tin về lỗi này không?

Để xóa mọi thứ:

Tôi biết làm thế nào để khắc phục vấn đề độ dài chuỗi. Điều tôi đang hỏi là làm thế nào để tôi có được tên trường chính xác đang phá vỡ mô hình.

Câu trả lời:


377

Trong khi bạn đang ở chế độ gỡ lỗi trong catch {...}khối, hãy mở cửa sổ "QuickWatch" ( ctrl+ alt+ q) và dán vào đó:

((System.Data.Entity.Validation.DbEntityValidationException)ex).EntityValidationErrors

Điều này sẽ cho phép bạn đi sâu vào ValidationErrorscây. Đó là cách dễ nhất mà tôi đã tìm thấy để có cái nhìn sâu sắc tức thì về những lỗi này.

Đối với người dùng Visual 2012+ chỉ quan tâm đến lỗi đầu tiên và có thể không có catchkhối, bạn thậm chí có thể thực hiện:

((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors.First().ValidationErrors.First().ErrorMessage

9
Điều này tốt hơn câu trả lời khác :)
Doug

98
Nếu bạn không có một khối catch, bạn có thể thay thế exvới $exceptionvà nhận được kết quả tương tự.
Ecyrb

cũng chắc chắn rằng bạn thay thế exvới w / e của bạn catch (Exception THIS)
Eonasdan

@Ecyrb, cảm ơn. bạn đã tiết kiệm được hàng giờ của Google. Ngoài ra, ngay cả khi số lỗi xác thực được hiển thị là 1, thực tế có hai phần tử trong mảng có hai lỗi.
ma trận

3
Đối với những người không tham khảo System.Linq và sử dụng cửa sổ ngay lập tức:System.Linq.Enumerable.ToList(System.Linq.Enumerable.ToList(((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors)[0].ValidationErrors)[0].ErrorMessage
jpsimard-nyx

124

Bạn có thể thử điều này trong một khối thử / bắt?

catch (DbEntityValidationException dbEx)
{
    foreach (var validationErrors in dbEx.EntityValidationErrors)
    {
        foreach (var validationError in validationErrors.ValidationErrors)
        {
            Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
        }
    }
}

11

Theo tôi, giải pháp tốt nhất là xử lý loại lỗi này một cách tập trung.

chỉ cần thêm phương thức này vào DbContextlớp chính :

public override int SaveChanges()
{
    try
    {
        return base.SaveChanges();
    }
    catch (DbEntityValidationException ex)
    {
        string errorMessages = string.Join("; ", ex.EntityValidationErrors.SelectMany(x => x.ValidationErrors).Select(x => x.PropertyName + ": " + x.ErrorMessage));
        throw new DbEntityValidationException(errorMessages);
    }
}

Điều này sẽ ghi đè lên SaveChanges()phương thức ngữ cảnh của bạn và bạn sẽ nhận được một danh sách được phân tách bằng dấu phẩy có chứa tất cả các lỗi xác thực thực thể.

hy vọng điều này là hữu ích.


4

Vâng, tôi đã có vấn đề tương tự. Mô hình của tôi hoạt động tốt trong EF CTP5 nhưng không thể xây dựng trong 4.1 với cùng một lỗi "" Xác thực không thành công cho một hoặc nhiều thực thể "khi tôi cố gắng kích hoạt nó. Tôi nhận ra rằng tôi có tài sản:

public string Comment {get; set;}

Sau đó, trong phương thức seed trong trình khởi tạo ghi đè, tôi đã có một nhận xét khá dài (khoảng 600 chữ cái).

Tôi nghĩ vấn đề là: trong EF 4.1, bạn phải đặt chú thích dữ liệu rõ ràng trong một số trường hợp. Đối với tôi, cài đặt:

[StringLength(4000)] 
public string Comment {get; set;}

đã giúp. Thật kỳ lạ vì CTP5 không có vấn đề gì với điều đó.


Vâng, điều tôi đã hỏi là làm thế nào để tôi có được tên tài sản chính xác đang phá vỡ mô hình. Mặc dù vậy, tôi đã cố gắng khắc phục sự cố mà bạn đã nêu bằng cách sử dụng [StringLạng (Int32.MaxValue)] làm thuộc tính cho tài sản của mình (như được đề xuất bởi Ladislav Mrnka và tôi đã nói về vấn đề này trong stackoverflow.com/questions/5346155/ ) Bột nghệ! =)
Naz

Điều này đã bị ném khi tôi thêm một thuộc tính mới vào mô hình của mình trong 4.1. Đã hoạt động hoàn hảo trong 4.1 trước đây. Kỳ dị. Giải quyết bằng cách thêm chú thích cho tất cả các thuộc tính trong mô hình.
Roberto Bonini

1

Tôi thấy hữu ích khi tạo một trình bao bọc SaveChanges giúp EntityValidationErrors dễ đọc hơn:

Public Sub SaveChanges(entities As Entities)

    Try
        entities.SaveChanges()

    Catch ex As DbEntityValidationException

        Dim msg As New StringBuilder
        msg.AppendLine(ex.Message)

        For Each vr As DbEntityValidationResult In ex.EntityValidationErrors
            For Each ve As DbValidationError In vr.ValidationErrors
                msg.AppendLine(String.Format("{0}: {1}", ve.PropertyName, ve.ErrorMessage))
            Next
        Next

        Throw New DbEntityValidationException(msg.ToString, ex.EntityValidationErrors, ex)

    End Try

End Sub

và sau đó thay đổi 'entity.SaveChanges ()' thành 'SaveChanges (thực thể)' trong toàn bộ dự án của tôi


0

Tôi biết đó là một câu hỏi cũ nhưng đây là câu trả lời của tôi:

catch (DbEntityValidationException ex)
   {
    String.Join("\n", ex.EntityValidationErrors
          .SelectMany(x => x.ValidationErrors)
          .Select(x => x.ErrorMessage)
          .ToArray());
   }

và nếu bạn sử dụng mã trước tiên, bạn cũng có thể toàn cầu hóa các thông báo lỗi của mình bằng nhiều tệp tài nguyên

Chẳng hạn, tôi có hai tệp tài nguyên riêng biệt này, một cho lỗi và một cho tên thuộc tính và tôi sử dụng chúng như sau: nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây

public class Person 
    {
        [Required(ErrorMessageResourceName = "required",ErrorMessageResourceType =typeof(ErrorMessages))]
        [MaxLength(100,ErrorMessageResourceName = "maxLength", ErrorMessageResourceType = typeof(ErrorMessages))]
        [Display(Name = "FirstName",ResourceType = typeof(Properties))]
        public string FirstName { get; set; }
         }

Như bạn có thể thấy tôi đã dịch hoàn toàn các thông báo lỗi của mình bao gồm cả tên thuộc tính, vì vậy sau đó tôi có thể sử dụng chúng trong người dùng:

nhập mô tả hình ảnh ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.