DbValidationException'dan tam hata türünü alma


184

Ben EF 4.1 DatabaseInitializer () benim modeli başlatılıyor ediyorum durum var ve bu can sıkıcı hata alıyorum "Validation failed for one or more entities. See 'EntityValidationErrors' property for more details."ben bu EntityValidationErrors gidip bir alan vardır, Yani {System.Data.Entity.Validation.DbEntityValidationResult}o başlatamadı hangi alanda yaklaşık hiç bana hiçbir bilgi verir . Bu hata hakkında daha fazla bilgi almanın bir yolu var mı?

Bir şeyleri temizlemek için:

Dize uzunluğu sorunu nasıl düzeltileceğini biliyorum. Sorduğum şey, modeli bozan tam alan adını nasıl alabilirim.

Yanıtlar:


377

catch {...}Blok içinde hata ayıklama modundayken "QuickWatch" penceresini ( ctrl+ alt+ q) açın ve buraya yapıştırın:

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

Bu, ValidationErrorsağaca inmenizi sağlar. Bu hataları anında anlamanın en kolay yolu.

Yalnızca ilk hatayı önemseyen ve bir catchbloğu olmayan Visual 2012+ kullanıcıları için şunları da yapabilirsiniz:

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

9
Bu diğer cevaptan daha iyidir :)
Doug

98
Eğer bir catch bloğu yoksa, sen yerini alabilir exile $exceptionve aynı sonucu alırsınız.
Ecyrb

Ayrıca emin değiştirmek yapmak ex/ e w ile senin catch (Exception THIS)olduğunu
Eonasdan

@Ecyrb, teşekkürler. saatlerce Google'ı kurtardınız. Ayrıca, doğrulama hatası sayısı 1 olarak gösterilse bile, dizide aslında iki hatayla iki öğe vardır.
matris

3
System.Linq'e System.Linq.Enumerable.ToList(System.Linq.Enumerable.ToList(((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors)[0].ValidationErrors)[0].ErrorMessage
başvurmayan

124

Bunu bir dene / yakala bloğunda deneyebilir misin?

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

Bence en iyi çözüm bu tür hataları merkezi bir şekilde ele almak.

bu yöntemi ana DbContextsınıfa eklemeniz yeterlidir:

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);
    }
}

Bu, bağlamınızın SaveChanges()yönteminin üzerine yazacak ve tüm varlık doğrulama hatalarını içeren virgülle ayrılmış bir liste alacaksınız.

umarım bu yardımcı olur.


4

Aynı problemim vardı. Modelim EF CTP5'te iyi çalıştı, ancak 4.1'de aynı hatayla "" Doğrulama bir veya daha fazla varlık için başarısız oldu "yapmayı başaramadığım zaman başarısız oldu.

public string Comment {get; set;}

Sonra geçersiz kılınmış başlatıcıda tohum yönteminde, biraz uzun (yaklaşık 600 harf) yorum vardı.

EF 4.1 Eğer: Ben noktası olduğunu düşünüyorum var bazı durumlarda açıkça belirlenmiş veri ek açıklama. Benim için, ayar:

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

yardım etti. CTP5'in bu konuda bir sorunu olmadığı için garip.


Sorduğum şey, modeli bozan tam özellik adını nasıl alabilirim. Yine de, mülküm için bir özellik olarak [StringLength (Int32.MaxValue)] kullanarak belirttiğiniz sorunun üstesinden gelmeyi başardım (Ladislav Mrnka tarafından önerildiği gibi ve bu soruda bu konu hakkında konuştum stackoverflow.com/questions/5346155/… Powodzenia! =)
Naz

4.1'de modelime yeni bir özellik eklediğimde bu atıldı. Daha önce 4.1'de mükemmel çalışıyordu. Tuhaf. Modeldeki tüm özelliklere ek açıklama ekleyerek çözüldü.
Roberto Bonini

1

EntityValidationErrors daha okunabilir kılan bir SaveChanges sarıcı oluşturmak için yararlı buldum:

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

ve ardından tüm projemdeki 'entities.SaveChanges ()' öğesini 'SaveChanges (entities)' olarak değiştirdi


0

Eski bir soru olduğunu biliyorum ama işte cevabım:

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

ve önce kodu kullanırsanız, hata mesajlarınızı birden fazla kaynak dosyası kullanarak globalleştirebilirsiniz

Örneğin, biri hata diğeri özellik adı için bu iki ayrı kaynak dosyası var ve bunları aşağıdaki gibi kullanıyorum: resim açıklamasını buraya girin resim açıklamasını buraya girin

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; }
         }

Gördüğünüz gibi, özellik adları da dahil olmak üzere hata mesajlarımı tamamen tercüme ettim, böylece bunları daha sonra örneğin kullanıcıda kullanabilirim:

resim açıklamasını buraya girin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.