Меню

Проверка одной или нескольких сущностей завершилась ошибкой

0 / 0 / 0

Регистрация: 12.06.2016

Сообщений: 9

1

Данные не сохраняются в БД

14.06.2016, 18:07. Показов 1469. Ответов 1


Компилятор выдает ошибку

Проверка одной или нескольких сущностей завершилась ошибкой. Более подробные сведения см. в свойстве «EntityValidationErrors».

Работаю в Visual Studio 2015 на C# с формами WPF, БД делал там же в конструкторе, Уже сохранял туда данные все работает, но именно на этом участке кода какие то проблемы

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
        //Добавление студента.............................................................
        private void button_update_Student_Click(object sender, RoutedEventArgs e)
        {
            var add_Variable = new Variable();
            var add_Students = new Student();
 
            var fgh = add_Variable.Number_Of_Students;
            var f = Convert.ToInt32(fgh);
            var g = f + 1;
            var h = Convert.ToString(g);
 
            add_Variable.Number_Of_Students = h;
            add_Students.Namber_Of_Cipher = h;
 
 
            add_Students.Surnam = textBox_Surname.Text;
            add_Students.Name = textBox_Name.Text;
            add_Students.Patronymic = textBox_Patroname.Text;
            add_Students.Telephone = textBox_Telephone.Text;
            add_Students.Number_Of_Encrollment = textBox_Namber_Of_Encrollment.Text;
            add_Students.Number_Of_Deductions = textBox_textBox_Namber_Of_Deductions.Text;
            add_Students.Cod_Student = textBox_Cod_Student.Text;
            add_Students.Location = textBox_Adress.Text;
 
 
 
            add_Students.Encrollment_Data = Encrollment_Data.SelectedDate.Value;
            add_Students.Deductions_Data = Deductions_Data.SelectedDate.Value;
 
 
            add_Students.School_Year = comboBox_class.ItemStringFormat;
            add_Students.Course = comboBox_Cours.ItemStringFormat;
            add_Students.Id_Group = (comboBox_Group.SelectedItem as Groupe).Id_Group;
            
 
 
            if (textBox_Surname.Text == "" || textBox_Name.Text == "" || textBox_Patroname.Text == "" || textBox_Telephone.Text == ""
                || textBox_Namber_Of_Encrollment.Text == "" || textBox_Cod_Student.Text == "" || Encrollment_Data == null || Deductions_Data == null
                || comboBox_class.SelectedItem == null || comboBox_Cours.SelectedItem == null || comboBox_Group.SelectedItem == null)
            {
                MessageBox.Show("Одно из полей не заполненно. Проверте все введенные данные", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            else
            {
                entities.Student.Add(add_Students);
                entities.SaveChanges();
 
                //comboBox_class.Items.Remove(add_Students);
                //comboBox_Cours.Items.Remove(add_Students);
                //comboBox_Group.Items.Remove(add_Students);
 
                listBox_Chifer.Items.Remove(add_Students);
                listBox_Name.Items.Remove(add_Students);
                listBox_Patroname.Items.Remove(add_Students);
 
            }
        }

А вот это весь код полностью

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
 
namespace Saochnic
{
    /// <summary>
    /// Логика взаимодействия для StudentWindow.xaml
    /// </summary>
    public partial class StudentWindow : Window
    {
        Entities entities = new Entities();
        public StudentWindow()
        {
            InitializeComponent();//Заполнение comboBox_Specialty
            foreach (var tyhg in entities.Specialty)
                {
                    comboBox_Specialty.Items.Add(tyhg);
                }
            InitializeComponent();//Заполнение comboBox_Group
            foreach (var hjk in entities.Groupe)
            {
                comboBox_Group.Items.Add(hjk);
            }
 
            InitializeComponent();//Заполнение comboBox_Cours
            {
                comboBox_Cours.Items.Add("1 курс");
                comboBox_Cours.Items.Add("2 курс");
                comboBox_Cours.Items.Add("3 курс");
                comboBox_Cours.Items.Add("4 курс");
            }
            InitializeComponent();//Заполнение comboBox_class
            {
                comboBox_class.Items.Add("9 классов");
                comboBox_class.Items.Add("11 классов");
            }
            InitializeComponent();//Заполнение listBox_Chifer $ listBox_Surname $ listBox_Name $ listBox_Patroname
            {
                foreach (var dwe in entities.Student)
                    listBox_Chifer.Items.Add(dwe.Namber_Of_Cipher);
                foreach (var uio in entities.Student)
                    listBox_Surname.Items.Add(uio);
                foreach (var nmb in entities.Student)
                    listBox_Name.Items.Add(nmb.Name);
                foreach (var fgh in entities.Student)
                    listBox_Patroname.Items.Add(fgh.Patronymic);
 
            }
            InitializeComponent();//Заполнение comboBox_group_delete
            foreach (var hg in entities.Groupe)
            {
                comboBox_group_delete.Items.Add(hg);
            }
        }
 
        private void button_Copy_Click(object sender, RoutedEventArgs e)
        {
            Hide();
            AdminWindows AdminWindows = new AdminWindows();
            AdminWindows.Show();
        }
        //Добавление группы...................................................................................................
        private void button_group_Click(object sender, RoutedEventArgs e)
        {
            var add_Group = new Groupe();
            add_Group.Name_Group = textBox_group.Text;
            if (textBox_group.Text == "")
            {
                MessageBox.Show("Не введено никакого значения. Введите название группы", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            else
            {
                entities.Groupe.Add(add_Group);
                entities.SaveChanges();
                comboBox_group_delete.Items.Add(add_Group);
                comboBox_Group.Items.Add(add_Group);
                textBox_group.Text = "";
                MessageBox.Show("Группа добавлена", "ОК", MessageBoxButton.OK, MessageBoxImage.Information);
            }
 
        }
        //Удаление группы...................................................................................................
        private void button_group_delete_Click(object sender, RoutedEventArgs e)
        {
            var delete_Group = comboBox_group_delete.SelectedItem as Groupe;
            if (delete_Group != null)
            {
                entities.Groupe.Remove(delete_Group);
                entities.SaveChanges();
                comboBox_group_delete.Items.Remove(delete_Group);
                comboBox_Group.Items.Remove(delete_Group);
 
            }
        }
        //Обработка событий ListBox_Surname................................................................................
        private void listBox_Surname_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var selected_Students = listBox_Surname.SelectedItem as Student;
            if (selected_Students != null)
            {
                //Вывод ноиера, имени и отчества в ListBox-ах......................
                listBox_Chifer.SelectedItem = selected_Students.Namber_Of_Cipher;
                listBox_Name.SelectedItem = selected_Students.Name;
                listBox_Patroname.SelectedItem = selected_Students.Patronymic;
 
                //Вывод даты.......................................................
                Encrollment_Data.SelectedDate = selected_Students.Encrollment_Data;
                Deductions_Data.SelectedDate = selected_Students.Deductions_Data;
                
                //Вывод текстовых полей (Имя, Фамилия, Отчество)...................
                textBox_Surname.Text = selected_Students.Surnam;
                textBox_Name.Text = selected_Students.Name;
                textBox_Patroname.Text = selected_Students.Patronymic;
                textBox_Telephone.Text = selected_Students.Telephone;
                textBox_Namber_Of_Encrollment.Text = selected_Students.Number_Of_Encrollment;
                textBox_textBox_Namber_Of_Deductions.Text = selected_Students.Number_Of_Deductions;
                textBox_Cod_Student.Text = selected_Students.Cod_Student;
                textBox_Adress.Text = selected_Students.Location;
 
                //Вывод курса, оконченных классов и специальности в ComboBox.......
                comboBox_class.SelectedItem = selected_Students.School_Year;
                comboBox_Cours.SelectedItem = selected_Students.Course;
                comboBox_Specialty.SelectedItem = (from ghnv in entities.Specialty where ghnv.Id_Specialty == selected_Students.Id_Specialty select ghnv).Single<Specialty>(); ;
                comboBox_Group.SelectedItem = (from grp in entities.Groupe where grp.Id_Group == selected_Students.Id_Group select grp).Single<Groupe>();
 
 
            }
            else
            {
                listBox_Chifer.SelectedItem = null;
                listBox_Name.SelectedItem = null;
                listBox_Patroname.SelectedItem = null;
 
 
                Encrollment_Data = null;
                Deductions_Data = null;
 
 
                textBox_Surname.Text = "";
                textBox_Name.Text = "";
                textBox_Patroname.Text = "";
                textBox_Telephone.Text = "";
                textBox_Namber_Of_Encrollment.Text = "";
                textBox_textBox_Namber_Of_Deductions.Text = "";
                textBox_Cod_Student.Text = "";
                textBox_Adress.Text = "";
 
 
 
                comboBox_class.SelectedIndex = -1;
                comboBox_Cours.SelectedIndex = -1;
                comboBox_Group.SelectedIndex = -1;
            }
        }
 
 
//..........................................................................................................................................................//
 
 
        //Добавление студента.............................................................
        private void button_update_Student_Click(object sender, RoutedEventArgs e)
        {
            var add_Variable = new Variable();
            var add_Students = new Student();
 
            var fgh = add_Variable.Number_Of_Students;
            var f = Convert.ToInt32(fgh);
            var g = f + 1;
            var h = Convert.ToString(g);
 
            add_Variable.Number_Of_Students = h;
            add_Students.Namber_Of_Cipher = h;
 
 
            add_Students.Surnam = textBox_Surname.Text;
            add_Students.Name = textBox_Name.Text;
            add_Students.Patronymic = textBox_Patroname.Text;
            add_Students.Telephone = textBox_Telephone.Text;
            add_Students.Number_Of_Encrollment = textBox_Namber_Of_Encrollment.Text;
            add_Students.Number_Of_Deductions = textBox_textBox_Namber_Of_Deductions.Text;
            add_Students.Cod_Student = textBox_Cod_Student.Text;
            add_Students.Location = textBox_Adress.Text;
 
 
 
            add_Students.Encrollment_Data = Encrollment_Data.SelectedDate.Value;
            add_Students.Deductions_Data = Deductions_Data.SelectedDate.Value;
 
 
            add_Students.School_Year = comboBox_class.ItemStringFormat;
            add_Students.Course = comboBox_Cours.ItemStringFormat;
            add_Students.Id_Group = (comboBox_Group.SelectedItem as Groupe).Id_Group;
            
 
 
            if (textBox_Surname.Text == "" || textBox_Name.Text == "" || textBox_Patroname.Text == "" || textBox_Telephone.Text == ""
                || textBox_Namber_Of_Encrollment.Text == "" || textBox_Cod_Student.Text == "" || Encrollment_Data == null || Deductions_Data == null
                || comboBox_class.SelectedItem == null || comboBox_Cours.SelectedItem == null || comboBox_Group.SelectedItem == null)
            {
                MessageBox.Show("Одно из полей не заполненно. Проверте все введенные данные", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            else
            {
                entities.Student.Add(add_Students);
                entities.SaveChanges();
 
                //comboBox_class.Items.Remove(add_Students);
                //comboBox_Cours.Items.Remove(add_Students);
                //comboBox_Group.Items.Remove(add_Students);
 
                listBox_Chifer.Items.Remove(add_Students);
                listBox_Name.Items.Remove(add_Students);
                listBox_Patroname.Items.Remove(add_Students);
 
            }
        }
        
 
    }
}

Добавлено через 1 минуту
Сама программа останавливается на строчке

C#
1
               entities.SaveChanges();

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



Я хочу сохранить свое редактирование в базе данных и использую Entity FrameWork Code-First в ASP.NET MVC 3/C#, но получаю ошибки. В моем классе Event у меня есть типы данных DateTime и TimeSpan, но в моей базе данных у меня есть дата и время соответственно. Может ли это быть причиной? Как я могу привести к соответствующему типу данных в коде перед сохранением изменений в базе данных.

public class Event
{
    public int EventId { get; set; }
    public int CategoryId { get; set; }
    public int PlaceId { get; set; }
    public string Title { get; set; }
    public decimal Price { get; set; }
    public DateTime EventDate { get; set; }
    public TimeSpan StartTime { get; set; }
    public TimeSpan EndTime { get; set; }
    public string Description { get; set; }
    public string EventPlaceUrl { get; set; }
    public Category Category { get; set; }
    public Place Place { get; set; }
}

Метод в контроллере >>>> Проблема в storeDB.SaveChanges();

// POST: /EventManager/Edit/386        
[HttpPost]
public ActionResult Edit(int id, FormCollection collection)
{
    var theEvent = storeDB.Events.Find(id);

    if (TryUpdateModel(theEvent))
    {
        storeDB.SaveChanges();
        return RedirectToAction("Index");
    }
    else
    {
        ViewBag.Categories = storeDB.Categories.OrderBy(g => g.Name).ToList();
        ViewBag.Places = storeDB.Places.OrderBy(a => a.Name).ToList();
        return View(theEvent);
    }
}

С участием

public class EventCalendarEntities : DbContext
{
    public DbSet<Event> Events { get; set; }
    public DbSet<Category> Categories { get; set; }
    public DbSet<Place> Places { get; set; } 
}

База данных SQL Server 2008 R2/T-SQL

EventDate (Datatype = date)  
StartTime (Datatype = time)  
EndTime (Datatype = time)  

HTTP-форма

EventDate (Datatype = DateTime) e.g. 4/8/2011 12:00:00 AM  
StartTime (Datatype = Timespan/time not sure) e.g. 08:30:00  
EndTime (Datatype = Timespan/time not sure) e.g. 09:00:00  

Ошибка сервера в приложении ‘/’

Ошибка проверки для одного или нескольких объектов. Для получения дополнительных сведений см. Свойство EntityValidationErrors.

Описание: необработанное исключение произошло во время выполнения текущего веб-запроса. Просмотрите трассировку стека, чтобы получить дополнительную информацию об ошибке и ее происхождении в коде.

Сведения об исключении: System.Data.Entity.Validation.DbEntityValidationException: ошибка проверки для одной или нескольких сущностей. Для получения дополнительных сведений см. Свойство EntityValidationErrors.

Ошибка источника:

Line 75:             if (TryUpdateModel(theEvent))
Line 76:             {
Line 77:                 storeDB.SaveChanges();
Line 78:                 return RedirectToAction("Index");
Line 79:             }

Исходный файл: C:sepMvcEventCalendarMvcEventCalendarControllersEventManagerController.cs Строка: 77

Трассировки стека:

[DbEntityValidationException: Ошибка проверки одного или нескольких объектов. Дополнительные сведения см. в свойстве EntityValidationErrors.]

17 ответов

Вы можете извлечь всю информацию из DbEntityValidationException с помощью следующего кода (вам нужно добавить пространства имен: System.Data.Entity.Validation и System.Diagnostics в ваш список using):

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


840

Marcus Mangelsdorf
8 Июл 2015 в 21:28

Изменение кода не требуется:

Пока вы находитесь в режиме отладки в блоке catch {...} откройте окно «QuickWatch» (Ctrl+Alt+Q) и вставить туда:

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

или:

((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors

Если вы не находитесь в try/catch или не имеете доступа к объекту исключения.

Это позволит вам углубиться в дерево ValidationErrors. Это самый простой способ получить мгновенное представление об этих ошибках.


249

GONeale
15 Мар 2016 в 02:29

Если у вас есть классы с одинаковыми именами свойств, вот небольшое расширение ответа Правина:

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


37

Michael0x2a
8 Июл 2015 в 20:54

В качестве улучшения для Правина и Тони я использую переопределение:

public partial class MyDatabaseEntities : DbContext
{
    public override int SaveChanges()
    {
        try
        {
            return base.SaveChanges();
        }
        catch (DbEntityValidationException dbEx)
        {
            foreach (var validationErrors in dbEx.EntityValidationErrors)
            {
                foreach (var validationError in validationErrors.ValidationErrors)
                {
                    Trace.TraceInformation("Class: {0}, Property: {1}, Error: {2}",
                        validationErrors.Entry.Entity.GetType().FullName,
                        validationError.PropertyName,
                        validationError.ErrorMessage);
                }
            }

            throw;  // You can also choose to handle the exception here...
        }
    }
}


22

Bolt Thunder
9 Авг 2012 в 18:36

Эта реализация переносит исключение объекта в исключение с подробным текстом. Он обрабатывает ошибки диапазона DbEntityValidationException, DbUpdateException, datetime2 (MS SQL) и включает ключ недопустимого объекта в сообщение (полезно при сохранении множества объектов за один вызов SaveChanges).

Во-первых, переопределите SaveChanges в классе DbContext:

public class AppDbContext : DbContext
{
    public override int SaveChanges()
    {
        try
        {
            return base.SaveChanges();
        }
        catch (DbEntityValidationException dbEntityValidationException)
        {
            throw ExceptionHelper.CreateFromEntityValidation(dbEntityValidationException);
        }
        catch (DbUpdateException dbUpdateException)
        {
            throw ExceptionHelper.CreateFromDbUpdateException(dbUpdateException);
        }
    }   

    public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken)
    {
        try
        {
            return await base.SaveChangesAsync(cancellationToken);
        }
        catch (DbEntityValidationException dbEntityValidationException)
        {
            throw ExceptionHelper.CreateFromEntityValidation(dbEntityValidationException);
        }
        catch (DbUpdateException dbUpdateException)
        {
            throw ExceptionHelper.CreateFromDbUpdateException(dbUpdateException);
        }
    }

Класс ExceptionHelper:

public class ExceptionHelper
{
    public static Exception CreateFromEntityValidation(DbEntityValidationException ex)
    {
        return new Exception(GetDbEntityValidationMessage(ex), ex);
    }

    public static string GetDbEntityValidationMessage(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);
        return exceptionMessage;
    }

    public static IEnumerable<Exception> GetInners(Exception ex)
    {
        for (Exception e = ex; e != null; e = e.InnerException)
            yield return e;
    }

    public static Exception CreateFromDbUpdateException(DbUpdateException dbUpdateException)
    {
        var inner = GetInners(dbUpdateException).Last();
        string message = "";
        int i = 1;
        foreach (var entry in dbUpdateException.Entries)
        {
            var entry1 = entry;
            var obj = entry1.CurrentValues.ToObject();
            var type = obj.GetType();
            var propertyNames = entry1.CurrentValues.PropertyNames.Where(x => inner.Message.Contains(x)).ToList();
            // check MS SQL datetime2 error
            if (inner.Message.Contains("datetime2"))
            {
                var propertyNames2 = from x in type.GetProperties()
                                        where x.PropertyType == typeof(DateTime) ||
                                            x.PropertyType == typeof(DateTime?)
                                        select x.Name;
                propertyNames.AddRange(propertyNames2);
            }

            message += "Entry " + i++ + " " + type.Name + ": " + string.Join("; ", propertyNames.Select(x =>
                string.Format("'{0}' = '{1}'", x, entry1.CurrentValues[x])));
        }
        return new Exception(message, dbUpdateException);
    }
}


6

Sel
21 Мар 2017 в 19:00

Этот код помог найти мою проблему, когда у меня возникла проблема с ошибками проверки сущности. Он сказал мне точную проблему с моим определением сущности. Попробуйте следующий код, где вам нужно покрыть storeDB.SaveChanges(); в следующей попытке поймать блок.

  try
{
         if (TryUpdateModel(theEvent))
         {
             storeDB.SaveChanges();
             return RedirectToAction("Index");
         }
}
catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
{
    Exception raise = dbEx;
    foreach (var validationErrors in dbEx.EntityValidationErrors)
    {
        foreach (var validationError in validationErrors.ValidationErrors)
        {
            string message = string.Format("{0}:{1}", 
                validationErrors.Entry.Entity.ToString(),
                validationError.ErrorMessage);
            // raise a new exception nesting
            // the current instance as InnerException
            raise = new InvalidOperationException(message, raise);
        }
    }
    throw raise;
}


5

Рахул Маквана
10 Апр 2016 в 03:50

Я получил эту ошибку сегодня и некоторое время не мог ее решить, но я понял, что это произошло после добавления некоторых RequireAttribute в мои модели, и что некоторые исходные данные разработки не заполняли все необходимые поля.< бр/> Так что обратите внимание: если вы получаете эту ошибку при обновлении базы данных с помощью какой-либо стратегии инициализации, такой как DropCreateDatabaseIfModelChanges, вы должны убедиться, что ваши исходные данные соответствуют всем атрибутам проверки данных модели< /сильный>.

Я знаю, что это немного отличается от проблемы в вопросе, но это популярный вопрос, поэтому я подумал, что добавлю немного больше к ответу для других, у которых такая же проблема, как у меня.
Надеюсь, это поможет другим 🙂


4

dan richardson
13 Дек 2012 в 14:51

Я думаю, что добавление try/catch для каждой операции SaveChanges() не является хорошей практикой, лучше централизовать это:

Добавьте этот класс в основной класс DbContext:

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

Это перезапишет метод SaveChanges() вашего контекста, и вы получите список, разделенный запятыми, содержащий все ошибки проверки сущности.

Это также может быть улучшено, чтобы регистрировать ошибки в рабочей среде, а не просто выдавать ошибку.

Надеюсь, что это полезно.


4

Chtiwi Malek
18 Апр 2015 в 21:45

Вот расширение расширения Тони… 🙂

Для Entity Framework 4.x, если вы хотите получить имя и значение ключевого поля, чтобы знать, какой экземпляр сущности (запись БД) имеет проблему, вы можете добавить следующее. Это обеспечивает доступ к более мощным членам класса ObjectContext из вашего объекта DbContext.

// Get the key field name & value.
// This assumes your DbContext object is "_context", and that it is a single part key.
var e = ((IObjectContextAdapter)_context).ObjectContext.ObjectStateManager.GetObjectStateEntry(validationErrors.Entry.Entity);
string key = e.EntityKey.EntityKeyValues[0].Key;
string val = e.EntityKey.EntityKeyValues[0].Value;


3

Martin_W
14 Апр 2012 в 13:38

Мне не нравятся исключения, я зарегистрировал OnSaveChanges и получил это

var validationErrors = model.GetValidationErrors();

var h = validationErrors.SelectMany(x => x.ValidationErrors
                                          .Select(f => "Entity: " 
                                                      +(x.Entry.Entity) 
                                                      + " : " + f.PropertyName 
                                                      + "->" + f.ErrorMessage));


3

johnny 5
14 Дек 2015 в 21:38

Эта ошибка также возникает при попытке сохранить сущность с ошибками проверки. Хороший способ вызвать это — забыть проверить ModelState.IsValid перед сохранением в БД.


2

laylarenee
20 Ноя 2013 в 23:24

Убедитесь, что если у вас есть nvarchar(50) в строке БД, вы не пытаетесь вставить в нее более 50 символов. Глупая ошибка, но мне потребовалось 3 часа, чтобы понять это.


2

user4030144
11 Сен 2014 в 12:52

Спасибо за ваши ответы, они мне очень помогают. поскольку я кодирую в Vb.Net, этот код Bolt для Vb.Net

Try
   Return MyBase.SaveChanges()
Catch dbEx As Validation.DbEntityValidationException
   For Each [error] In From validationErrors In dbEx.EntityValidationErrors
                       From validationError In validationErrors.ValidationErrors
                       Select New With { .PropertyName = validationError.PropertyName,
                                         .ErrorMessage = validationError.ErrorMessage,
                                         .ClassFullName = validationErrors.Entry.Entity
                                                                    .GetType().FullName}

        Diagnostics.Trace.TraceInformation("Class: {0}, Property: {1}, Error: {2}",
                                           [error].ClassFullName,
                                           [error].PropertyName,
                                           [error].ErrorMessage)
   Next
   Throw
End Try


1

johnny 5
14 Дек 2015 в 21:37

Это может быть вызвано свойством, которое не заполняется моделью.. вместо этого оно заполняется контроллером.. что может вызвать эту ошибку.. решение этой проблемы — назначить свойство перед применением проверки ModelState. и это второе предположение есть . возможно, у вас уже есть данные в вашей базе данных, и вы пытаетесь их обновить, но теперь извлекаете их.


1

Muhammad Mustafa
13 Апр 2016 в 22:30

Это может быть связано с максимальным количеством символов, разрешенным для определенного столбца, например, в sql одно поле может иметь следующий тип данных nvarchar(5), но количество символов, введенных пользователем, больше указанного, поэтому возникает ошибка .


1

lokopi
1 Июн 2016 в 11:00

Я столкнулся с той же проблемой пару дней назад при обновлении базы данных. В моем случае для обслуживания было добавлено несколько новых столбцов, не допускающих значение NULL, которые не были указаны в коде, вызывающем исключение. Я выясняю эти поля и предоставляю для них значения, и это разрешено.


1

Jhabar
5 Фев 2017 в 06:40

В моем случае у меня есть имя столбца таблицы Path, для которого я установил тип данных varchar (200). После обновления его до nvarchar (max) я удалил таблицу из edmx, а затем снова добавил таблицу, и она работала правильно для меня.


1

Saket Singh
20 Фев 2019 в 14:39

I have following code in my asp.net MVC3 application:

string msg = "Beginning report run for: ";
            msg += " Obligor Registry ID: " + obligorID;
            msg += " Requesting Organization Registry ID:" + requestingOrgID;
            msg += " Requesting Agent Registry ID: " + requestingAgentID;

            TransactionLog lg = new TransactionLog();
            lg.TransactionTypeId = 2;
            lg.Message = msg;    


             context.TransactionLogs.Add(lg);
             long referenceNumber = context.SaveChanges();
            return referenceNumber;

and I am getting following error:

Validation failed for one or more entities. See 'EntityValidationErrors' property for more details. 

Darin Dimitrov's user avatar

asked May 28, 2011 at 11:01

DotnetSparrow's user avatar

DotnetSparrowDotnetSparrow

26.9k62 gold badges179 silver badges314 bronze badges

4

While you are in debug mode within the catch {...} block open up the «QuickWatch» window (ctrl+alt+q) and paste in there:

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

This will allow you to drill down into the ValidationErrors tree. It’s the easiest way I’ve found to get instant insight into these errors.

answered Aug 25, 2011 at 1:24

GONeale's user avatar

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

You need the namespace: System.Data.Entity.Validation

answered Jun 10, 2013 at 9:21

Yasser Shaikh's user avatar

Yasser ShaikhYasser Shaikh

46.5k44 gold badges200 silver badges280 bronze badges

@GONeale helped me out in this regard. Moreover cause for this exception in my case is that I have certain not null db fields which I didnt included in the partial response update for certain transaction. context.Database.ExecuteSQLCommand would be my suggestion in this case.

answered Dec 18, 2013 at 13:06

zeeshan's user avatar

I have following code in my asp.net MVC3 application:

string msg = "Beginning report run for: ";
            msg += " Obligor Registry ID: " + obligorID;
            msg += " Requesting Organization Registry ID:" + requestingOrgID;
            msg += " Requesting Agent Registry ID: " + requestingAgentID;

            TransactionLog lg = new TransactionLog();
            lg.TransactionTypeId = 2;
            lg.Message = msg;    


             context.TransactionLogs.Add(lg);
             long referenceNumber = context.SaveChanges();
            return referenceNumber;

and I am getting following error:

Validation failed for one or more entities. See 'EntityValidationErrors' property for more details. 

Darin Dimitrov's user avatar

asked May 28, 2011 at 11:01

DotnetSparrow's user avatar

DotnetSparrowDotnetSparrow

26.9k62 gold badges179 silver badges314 bronze badges

4

While you are in debug mode within the catch {...} block open up the «QuickWatch» window (ctrl+alt+q) and paste in there:

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

This will allow you to drill down into the ValidationErrors tree. It’s the easiest way I’ve found to get instant insight into these errors.

answered Aug 25, 2011 at 1:24

GONeale's user avatar

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

You need the namespace: System.Data.Entity.Validation

answered Jun 10, 2013 at 9:21

Yasser Shaikh's user avatar

Yasser ShaikhYasser Shaikh

46.5k44 gold badges200 silver badges280 bronze badges

@GONeale helped me out in this regard. Moreover cause for this exception in my case is that I have certain not null db fields which I didnt included in the partial response update for certain transaction. context.Database.ExecuteSQLCommand would be my suggestion in this case.

answered Dec 18, 2013 at 13:06

zeeshan's user avatar

у меня эта ошибка при заполнении базы данных с кодом первого подхода.

ошибка проверки для одного или нескольких объектов. Дополнительные сведения см. В разделе свойство ‘EntityValidationErrors’.

честно говоря, я не знаю, как проверить контент на ошибки валидации. Visual Studio показывает мне, что это массив с 8 объектами, поэтому 8 ошибок проверки.

это работало с моей предыдущей моделью, но я внес несколько изменений, которые я объясняю ниже:

  • у меня было перечисление Status, я изменил его на класс Status
  • Я изменил класс ApplicantsPositionHistory, чтобы иметь 2 внешних ключа к той же таблице

извините меня за длинный код, но я должен вставить все это. Исключение создается в последней строке следующего кода.

namespace Data.Model
{  
    public class Position
    {
        [DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.Identity)]   
        public int PositionID { get; set; }

        [Required(ErrorMessage = "Position name is required.")]
        [StringLength(20, MinimumLength = 3, ErrorMessage = "Name should not be longer than 20 characters.")]
        [Display(Name = "Position name")]              
        public string name { get; set; }

        [Required(ErrorMessage = "Number of years is required")] 
        [Display(Name = "Number of years")]        
        public int yearsExperienceRequired { get; set; }

        public virtual ICollection<ApplicantPosition> applicantPosition { get; set; }
    }

    public class Applicant
    {
        [DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.Identity)]      
        public int ApplicantID { get; set; }

        [Required(ErrorMessage = "Name is required")] 
        [StringLength(20, MinimumLength = 3, ErrorMessage="Name should not be longer than 20 characters.")]
        [Display(Name = "First and LastName")]
        public string name { get; set; }

        [Required(ErrorMessage = "Telephone number is required")] 
        [StringLength(10, MinimumLength = 3, ErrorMessage = "Telephone should not be longer than 20 characters.")]
        [Display(Name = "Telephone Number")]
        public string telephone { get; set; }

        [Required(ErrorMessage = "Skype username is required")] 
        [StringLength(10, MinimumLength = 3, ErrorMessage = "Skype user should not be longer than 20 characters.")]
        [Display(Name = "Skype Username")]
        public string skypeuser { get; set; }

        public byte[] photo { get; set; }

        public virtual ICollection<ApplicantPosition> applicantPosition { get; set; }
    }

    public class ApplicantPosition
    {
        [Key]
        [Column("ApplicantID", Order = 0)]
        public int ApplicantID { get; set; }

        [Key]
        [Column("PositionID", Order = 1)]
        public int PositionID { get; set; }

        public virtual Position Position { get; set; }

        public virtual Applicant Applicant { get; set; }

        [Required(ErrorMessage = "Applied date is required")] 
        [DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
        [Display(Name = "Date applied")]     
        public DateTime appliedDate { get; set; }

        [Column("StatusID", Order = 0)]
        public int StatusID { get; set; }

        public Status CurrentStatus { get; set; }

        //[NotMapped]
        //public int numberOfApplicantsApplied
        //{
        //    get
        //    {
        //        int query =
        //             (from ap in Position
        //              where ap.Status == (int)Status.Applied
        //              select ap
        //                  ).Count();
        //        return query;
        //    }
        //}
    }

    public class Address
    {
        [StringLength(20, MinimumLength = 3, ErrorMessage = "Country should not be longer than 20 characters.")]
        public string Country { get; set; }

        [StringLength(20, MinimumLength = 3, ErrorMessage = "City  should not be longer than 20 characters.")]
        public string City { get; set; }

        [StringLength(50, MinimumLength = 3, ErrorMessage = "Address  should not be longer than 50 characters.")]
        [Display(Name = "Address Line 1")]     
        public string AddressLine1 { get; set; }

        [Display(Name = "Address Line 2")]
        public string AddressLine2 { get; set; }   
    }

    public class ApplicationPositionHistory
    {
        [DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.Identity)]
        public int ApplicationPositionHistoryID { get; set; }

        public ApplicantPosition applicantPosition { get; set; }

        [Column("oldStatusID")]
        public int oldStatusID { get; set; }

        [Column("newStatusID")]
        public int newStatusID { get; set; }

        public Status oldStatus { get; set; }

        public Status newStatus { get; set; }

        [StringLength(500, MinimumLength = 3, ErrorMessage = "Comments  should not be longer than 500 characters.")]
        [Display(Name = "Comments")]
        public string comments { get; set; }

        [DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
        [Display(Name = "Date")]     
        public DateTime dateModified { get; set; }
    }

    public class Status
    {
        [DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.Identity)]
        public int StatusID { get; set; }

        [StringLength(20, MinimumLength = 3, ErrorMessage = "Status  should not be longer than 20 characters.")]
        [Display(Name = "Status")]
        public string status { get; set; }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.IO;

namespace Data.Model
{
    public class HRContextInitializer : DropCreateDatabaseAlways<HRContext>
    {
        protected override void Seed(HRContext context)
        {
            #region Status
            Status applied = new Status() { status = "Applied" };
            Status reviewedByHR = new Status() { status = "Reviewed By HR" };
            Status approvedByHR = new Status() { status = "Approved by HR" };
            Status rejectedByHR = new Status() { status = "Rejected by HR" };
            Status assignedToTechnicalDepartment = new Status() { status = "Assigned to Technical Department" };
            Status approvedByTechnicalDepartment = new Status() { status = "Approved by Technical Department" };
            Status rejectedByTechnicalDepartment = new Status() { status = "Rejected by Technical Department" };

            Status assignedToGeneralManager = new Status() { status = "Assigned to General Manager" };
            Status approvedByGeneralManager = new Status() { status = "Approved by General Manager" };
            Status rejectedByGeneralManager = new Status() { status = "Rejected by General Manager" };

            context.Status.Add(applied);
            context.Status.Add(reviewedByHR);
            context.Status.Add(approvedByHR);
            context.Status.Add(rejectedByHR);
            context.Status.Add(assignedToTechnicalDepartment);
            context.Status.Add(approvedByTechnicalDepartment);
            context.Status.Add(rejectedByTechnicalDepartment);
            context.Status.Add(assignedToGeneralManager);
            context.Status.Add(approvedByGeneralManager);
            context.Status.Add(rejectedByGeneralManager); 
            #endregion    

            #region Position
            Position netdeveloper = new Position() { name = ".net developer", yearsExperienceRequired = 5 };
            Position javadeveloper = new Position() { name = "java developer", yearsExperienceRequired = 5 };
            context.Positions.Add(netdeveloper);
            context.Positions.Add(javadeveloper); 
            #endregion

            #region Applicants
            Applicant luis = new Applicant()
            {
                name = "Luis",
                skypeuser = "le.valencia",
                telephone = "0491732825",
                photo = File.ReadAllBytes(@"C:UsersLUIS.SIMBIOSDocumentsVisual Studio 2010ProjectsSlnHRHRRazorFormsContentpictures.jpg")
            };

            Applicant john = new Applicant()
            {
                name = "John",
                skypeuser = "jo.valencia",
                telephone = "3435343543",
                photo = File.ReadAllBytes(@"C:UsersLUIS.SIMBIOSDocumentsVisual Studio 2010ProjectsSlnHRHRRazorFormsContentpictures.jpg")
            };

            context.Applicants.Add(luis);
            context.Applicants.Add(john); 
            #endregion

            #region ApplicantsPositions
            ApplicantPosition appicantposition = new ApplicantPosition()
            {
                Applicant = luis,
                Position = netdeveloper,
                appliedDate = DateTime.Today,
                StatusID = 1
            };

            ApplicantPosition appicantposition2 = new ApplicantPosition()
            {
                Applicant = john,
                Position = javadeveloper,
                appliedDate = DateTime.Today,
                StatusID = 1
            };        

            context.ApplicantsPositions.Add(appicantposition);            
            context.ApplicantsPositions.Add(appicantposition2); 
            #endregion

            context.SaveChanges(); --->> Error here
        }
    }
}

24 ответов


честно говоря, я не знаю, как проверить контент на ошибки валидации. Visual Studio показывает мне, что это массив с 8 объектами, поэтому 8 ошибок проверки.

на самом деле вы должны увидеть ошибки, если вы детализируете этот массив в Visual studio во время отладки. Но вы также можете поймать исключение, а затем записать ошибки в какое-либо хранилище журналов или консоль:

try
{
    // Your code...
    // Could also be before try if you know the exception occurs in SaveChanges

    context.SaveChanges();
}
catch (DbEntityValidationException e)
{
    foreach (var eve in e.EntityValidationErrors)
    {
        Console.WriteLine("Entity of type "{0}" in state "{1}" has the following validation errors:",
            eve.Entry.Entity.GetType().Name, eve.Entry.State);
        foreach (var ve in eve.ValidationErrors)
        {
            Console.WriteLine("- Property: "{0}", Error: "{1}"",
                ve.PropertyName, ve.ErrorMessage);
        }
    }
    throw;
}

EntityValidationErrors представляет собой коллекцию, которая представляет сущности который не может быть успешно проверен, и внутренняя коллекция ValidationErrors per entity-это список ошибок на уровне свойств.

эти сообщения проверки обычно достаточно полезно, чтобы найти источник проблемы.

редактировать

несколько незначительных улучшений:

на стоимостью оскорбительного свойства может быть включен во внутренний цикл, как так:

        foreach (var ve in eve.ValidationErrors)
        {
            Console.WriteLine("- Property: "{0}", Value: "{1}", Error: "{2}"",
                ve.PropertyName,
                eve.Entry.CurrentValues.GetValue<object>(ve.PropertyName),
                ve.ErrorMessage);
        }

во время отладки Debug.Write может быть предпочтительнее Console.WriteLine поскольку он работает во всех видах приложений, а не только в консольных приложениях (спасибо @Bart за его заметку в комментариях ниже).

для веб-приложений, которые находятся в производстве и использовании Elmah для регистрации исключений оказалось очень полезным создать пользовательское исключение и перезаписать SaveChanges для того, чтобы бросить это новое исключение.

пользовательский тип исключения выглядит так:

public class FormattedDbEntityValidationException : Exception
{
    public FormattedDbEntityValidationException(DbEntityValidationException innerException) :
        base(null, innerException)
    {
    }

    public override string Message
    {
        get
        {
            var innerException = InnerException as DbEntityValidationException;
            if (innerException != null)
            {
                StringBuilder sb = new StringBuilder();

                sb.AppendLine();
                sb.AppendLine();
                foreach (var eve in innerException.EntityValidationErrors)
                {
                    sb.AppendLine(string.Format("- Entity of type "{0}" in state "{1}" has the following validation errors:",
                        eve.Entry.Entity.GetType().FullName, eve.Entry.State));
                    foreach (var ve in eve.ValidationErrors)
                    {
                        sb.AppendLine(string.Format("-- Property: "{0}", Value: "{1}", Error: "{2}"",
                            ve.PropertyName,
                            eve.Entry.CurrentValues.GetValue<object>(ve.PropertyName),
                            ve.ErrorMessage));
                    }
                }
                sb.AppendLine();

                return sb.ToString();
            }

            return base.Message;
        }
    }
}

и SaveChanges можно переписать следующим образом:

public class MyContext : DbContext
{
    // ...

    public override int SaveChanges()
    {
        try
        {
            return base.SaveChanges();
        }
        catch (DbEntityValidationException e)
        {
            var newException = new FormattedDbEntityValidationException(e);
            throw newException;
        }
    }
}

несколько замечаний:

  • желтый экран ошибки, который Elmah показывает в веб-интерфейсе или в отправленных электронных письмах (если вы настроили это) теперь отображает детали проверки непосредственно в верхней части сообщения.

  • перезаписи Message свойство в пользовательском исключении вместо перезаписи ToString() имеет преимущество которое стандарт ASP.NET » желтый экран смерти (YSOD) » также отображает это сообщение. В отличие от Elmah YSOD, по-видимому, не использует ToString(), но и отобразить Message собственность.

  • упаковка оригинал DbEntityValidationException как внутреннее исключение гарантирует, что исходная трассировка стека по-прежнему будет доступна и отображается в Elmah и YSOD.

  • , установив точку останова на строку throw newException; вы можете просто проверить newException.Message свойство в виде текста вместо бурение в коллекции проверки, что немного неудобно и, похоже, не работает легко для всех (см. комментарии ниже).


вы можете сделать это из Visual Studio во время отладки без написания кода, даже блока catch.

просто добавьте часы с именем:

((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors

часы выражение $exception отображает любое исключение, созданное в текущем контексте, даже если оно не было поймано и назначено переменной.

на основе http://mattrandle.me/viewing-entityvalidationerrors-in-visual-studio/


это действительно может сделать это без необходимости писать код:

в блоке catch добавьте точку останова в следующей строке кода:

catch (Exception exception)
{

}

Теперь, если вы наведете курсор на exception на Watch а затем перейдите к деталям исключения, как показано ниже; вы увидите, какие конкретные столбцы / вызывают проблему, поскольку эта ошибка обычно возникает при нарушении ограничения таблицы..

enter image description here

большие изображение


вот как вы можете проверить содержимое EntityValidationErrors в Visual Studio (без написания дополнительного кода), т. е. во время отладка на IDE.

Проблема?

вы правы, отладчик Visual Studio Посмотреть Подробнее всплывающее окно не показывает фактические ошибки внутри EntityValidationErrors коллекция .

enter image description here

в Решение!

просто добавьте следующее выражение в Быстрая Смотреть окне и нажмите кнопку переоценка.

((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors

в моем случае посмотрите, как я могу расшириться в ValidationErrors List внутри EntityValidationErrors коллекция

enter image description here

ссылки: маттрандл.me blog post, @Йоэль это


для быстрого способа увидеть первую ошибку, даже не добавляя часы, вы можете вставить это в ближайшее окно:

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

для всех, кто работает в VB.NET

Try
Catch ex As DbEntityValidationException
    For Each a In ex.EntityValidationErrors
        For Each b In a.ValidationErrors
            Dim st1 As String = b.PropertyName
            Dim st2 As String = b.ErrorMessage
        Next
    Next
End Try

пока вы находитесь в режиме отладки в catch {...} блок откройте окно «QuickWatch» (ctrl+alt+q) и вставить туда:

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

или:

((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors

если вы не находитесь в try / catch или не имеете доступа к объекту исключения.

Это позволит вам углубиться в ValidationErrors дерево. Это самый простой способ я нашел, чтобы получить мгновенный понимание этих ошибок.


Если вы просто ловите общее исключение, это может принести вам пользу, чтобы бросить это как DbEntityValidationException. Этот тип исключения имеет свойство ошибки проверки, и продолжая расширять свой путь в них, вы найдете все проблемы.

например, если вы поместите точку останова в ловушку, вы можете бросить следующее в часы:

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

пример ошибки Если поле не допускает значения NULL, и у вас есть нулевая строка, вы увидите, что она говорит, что поле обязательно.


в debug вы можете ввести это в поле ввода quickwatch expression evaluator:

context.GetValidationErrors()

просто проверьте длину поля таблицы базы данных .
Ваш входной текст больше длины поля столбца типа данных length


Я должен был написать это в ближайшем окне: 3

(((exception as System.Data.Entity.Validation.DbEntityValidationException).EntityValidationErrors as System.Collections.Generic.List<System.Data.Entity.Validation.DbEntityValidationResult>)[0].ValidationErrors as System.Collections.Generic.List<System.Data.Entity.Validation.DbValidationError>)[0]

для того, чтобы углубиться в точную ошибку !


отметим, что Entity.GetType().BaseType.Name дает указанное вами имя типа, а не имя со всеми шестнадцатеричными цифрами в его имени.


используя ответ @Slauma, я сделал фрагмент кода (окружение с фрагментом) для лучшего использования.

<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <SnippetTypes>
        <SnippetType>SurroundsWith</SnippetType>
      </SnippetTypes>
      <Title>ValidationErrorsTryCatch</Title>
      <Author>Phoenix</Author>
      <Description>
      </Description>
      <HelpUrl>
      </HelpUrl>
      <Shortcut>
      </Shortcut>
    </Header>
    <Snippet>
      <Code Language="csharp"><![CDATA[try
{
    $selected$ $end$
}
catch (System.Data.Entity.Validation.DbEntityValidationException e)
{
    foreach (var eve in e.EntityValidationErrors)
    {
        Console.WriteLine("Entity of type "{0}" in state "{1}" has the following validation errors:",
            eve.Entry.Entity.GetType().Name, eve.Entry.State);
        foreach (var ve in eve.ValidationErrors)
        {
            Console.WriteLine("- Property: "{0}", Error: "{1}"",
                ve.PropertyName, ve.ErrorMessage);
        }
    }
    throw;
}]]></Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

за ответ @Slauma и предложение @Milton я расширил пользовательский метод сохранения нашего базового класса с помощью try / catch, который будет обрабатывать (и, следовательно, войти в наш журнал ошибок!) такого рода исключения.

// Where `BaseDB` is your Entities object... (it could be `this` in a different design)
public void Save(bool? validateEntities = null)
{
    try
    {
        //Capture and set the validation state if we decide to
        bool validateOnSaveEnabledStartState = BaseDB.Configuration.ValidateOnSaveEnabled;
        if (validateEntities.HasValue)
            BaseDB.Configuration.ValidateOnSaveEnabled = validateEntities.Value;

        BaseDB.SaveChanges();

        //Revert the validation state when done
        if (validateEntities.HasValue)
            BaseDB.Configuration.ValidateOnSaveEnabled = validateOnSaveEnabledStartState;
    }
    catch (DbEntityValidationException e)
    {
        StringBuilder sb = new StringBuilder();
        foreach (var eve in e.EntityValidationErrors)
        {
            sb.AppendLine(string.Format("Entity of type "{0}" in state "{1}" has the following validation errors:", 
                                            eve.Entry.Entity.GetType().Name,
                                            eve.Entry.State));
            foreach (var ve in eve.ValidationErrors)
            {
                sb.AppendLine(string.Format("- Property: "{0}", Error: "{1}"",
                                            ve.PropertyName,
                                            ve.ErrorMessage));
            }
        }
        throw new DbEntityValidationException(sb.ToString(), e);
    }
}

поймать исключение в попытке поймать, а затем быстрый просмотр или ctrl+d & ctrl+q, и вы можете перейти к EntityValidationErrors.


ответ от @Slauma действительно велик, но я обнаружил, что он не работает, когда свойство ComplexType недействительно.

например, скажем, у вас есть собственность Phone сложного типа PhoneNumber. Если AreaCode свойство недопустимо, имя свойства в ve.PropertyNames это «телефон.Зоны». Это вызывает вызов eve.Entry.CurrentValues<object>(ve.PropertyName) на провал.

чтобы исправить это, вы можете разделить собственность на имя каждого ., затем повторить через результирующий массив имен свойств. В конечном счете, когда вы прибудете в нижнюю часть цепочки, вы можете просто вернуть значение свойства.

ниже @Slauma это FormattedDbEntityValidationException класс с поддержкой сложных типов.

наслаждайтесь!

[Serializable]
public class FormattedDbEntityValidationException : Exception
{
    public FormattedDbEntityValidationException(DbEntityValidationException innerException) :
        base(null, innerException)
    {
    }

    public override string Message
    {
        get
        {
            var innerException = InnerException as DbEntityValidationException;
            if (innerException == null) return base.Message;

            var sb = new StringBuilder();

            sb.AppendLine();
            sb.AppendLine();
            foreach (var eve in innerException.EntityValidationErrors)
            {
                sb.AppendLine(string.Format("- Entity of type "{0}" in state "{1}" has the following validation errors:",
                    eve.Entry.Entity.GetType().FullName, eve.Entry.State));
                foreach (var ve in eve.ValidationErrors)
                {
                    object value;
                    if (ve.PropertyName.Contains("."))
                    {
                        var propertyChain = ve.PropertyName.Split('.');
                        var complexProperty = eve.Entry.CurrentValues.GetValue<DbPropertyValues>(propertyChain.First());
                        value = GetComplexPropertyValue(complexProperty, propertyChain.Skip(1).ToArray());
                    }
                    else
                    {
                        value = eve.Entry.CurrentValues.GetValue<object>(ve.PropertyName);
                    }
                    sb.AppendLine(string.Format("-- Property: "{0}", Value: "{1}", Error: "{2}"",
                        ve.PropertyName,
                        value,
                        ve.ErrorMessage));
                }
            }
            sb.AppendLine();

            return sb.ToString();
        }
    }

    private static object GetComplexPropertyValue(DbPropertyValues propertyValues, string[] propertyChain)
    {
        var propertyName = propertyChain.First();
        return propertyChain.Count() == 1 
            ? propertyValues[propertyName] 
            : GetComplexPropertyValue((DbPropertyValues)propertyValues[propertyName], propertyChain.Skip(1).ToArray());
    }
}

просто бросаю свои два цента…

в моей dbConfiguration.cs, мне нравится обертывать мой контекст.Метод SaveChanges () в try/catch и создает выходной текстовый файл, который позволяет мне четко читать ошибки, и этот код также помечает их — удобно, если вы сталкиваетесь с более чем одной ошибкой в разное время!

        try
        {
            context.SaveChanges();
        }
        catch (DbEntityValidationException e)
        {
            //Create empty list to capture Validation error(s)
            var outputLines = new List<string>();

            foreach (var eve in e.EntityValidationErrors)
            {
                outputLines.Add(
                    $"{DateTime.Now}: Entity of type "{eve.Entry.Entity.GetType().Name}" in state "{eve.Entry.State}" has the following validation errors:");
                outputLines.AddRange(eve.ValidationErrors.Select(ve =>
                    $"- Property: "{ve.PropertyName}", Error: "{ve.ErrorMessage}""));
            }
            //Write to external file
            File.AppendAllLines(@"c:tempdbErrors.txt", outputLines);
            throw;
        }

Что я нашел…когда я получил ошибку ‘EntityValidationErrors-это….у меня есть поле в моей базе данных » db1 «в таблице» tbladdress » как «address1», которое имеет размер 100 (i.e адрес varchar (100) null), и я передавал значение более 100 символов..и это приводит к ошибке при сохранении данных в базе данных….

поэтому вы должны проверить данные, которые вы передаете на поле.

4

автор: Dharmendra Prajapati


это работает для меня.

var modelState = ModelState.Values;
if (!ModelState.IsValid)
{
    return RedirectToAction("Index", "Home", model);
}

поместите точку останова в Оператор if.
Затем вы можете проверить modelState в отладочных окнах. На каждом значении вы можете увидеть, есть ли ошибка и даже сообщение об ошибке. Вот и все.
Когда вам это больше не нужно, просто удалите или прокомментируйте строку.

надеюсь, это поможет.

Если меня спросят, я могу предоставить подробный снимок экрана в окне отладки.


Как упоминалось в других сообщениях, просто поймайте исключение в классе DbEntityValidationException.
Который даст вам watever, который вам нужен во время случаев ошибок.

 try
 {
  ....
 }
 catch(DbEntityValidationException ex)
 {
  ....
 }

я столкнулся с этой ошибки, перед

когда я попытался обновить конкретное поле в моей модели в entity framwork

Letter letter = new Letter {ID = letterId, ExportNumber = letterExportNumber,EntityState = EntityState.Modified};
LetterService.ChangeExportNumberfor(letter);
//----------


public int ChangeExportNumber(Letter letter)
    {
        int result = 0;
        using (var db = ((LettersGeneratorEntities) GetContext()))
        {
            db.Letters.Attach(letter);
            db.Entry(letter).Property(x => x.ExportNumber).IsModified = true;
            result += db.SaveChanges();
        }
        return result;
    }

и в соответствии с вышеуказанными ответами

Я нашел сообщение проверки The SignerName field is required.

, который указывает на поле в моей модели

и когда я проверил свою схему базы данных, я нашел

enter image description here

так off coure ValidationException имеет право поднять

и в соответствии с этим полем я хочу, чтобы он был недействительным, (я не знаю, как я его испортил)

поэтому я изменил это поле, чтобы разрешить Null, и по этому мой код не даст мне эту ошибку снова

Так что эта ошибка может произойти, если вы аннулируете целостность данных вашей базы данных

2

автор: Basheer AL-MOMANI


пожалуйста, проверьте значения полей, которые вы передаете, действительны и в соответствии с полями базы данных. Например, количество символов, переданных в определенном поле, меньше, чем символы, определенные в поле таблицы базы данных.


если вы используете IIS С Аутентификация Windows и Entity Framework, будьте осторожны, чтобы использовать authorize.

пробовал POST без авторизации и это не сработало, и получаете эту ошибку на db.SaveChangesAsync();, в то время как все остальные глаголы GET и DELETE работали.

но когда я добавил AuthorizeAttribute в качестве аннотации, это сработало.

[Authorize]
public async Task<IHttpActionResult> Post(...){
....
}

проверить, есть ли у вас Not Null ограничение в столбцах таблицы, и вы не передаете значение для этого столбца во время операций вставки/обновления.
Это вызывает это исключение в entity framework.


При использовании Entity Framework вы можете столкнуться с ошибкой, гласящей «Validation failed for one or more entities. See ‘EntityValidationErrors’ property for more details.» Причина появления этой ошибки в большинстве случаев — банальна, либо вы забыли какие ограничения существуют на полях в вашей базе данных, либо, если БД в вашей компании занимается отдельный человек, то он вам забыл о чем-то сообщить. 😉

EntityValidationErrors — это коллекция объектов DbEntityValidationResult, каждый из которых содержит информацию об ошибках одной EF-сущности в виде объектов DbValidationError.
На самом деле, ничего страшного в этой ошибке нет, и можно легко узнать в чем конкретно у нас ошибка в коде. Все, что для этого необходимо — это обернуться вызов метода SaveChanges() вот в такой блок try-catch:

 
                try
                {

                    DB.DB.SaveChanges();

                }
                catch (DbEntityValidationException ex)
                {
                    foreach (DbEntityValidationResult validationError in ex.EntityValidationErrors)
                    {
                        Response.Write("Object: "+validationError.Entry.Entity.ToString());
                        Response.Write("
");
                        foreach (DbValidationError err in validationError.ValidationErrors)
                        {
                            Response.Write(err.ErrorMessage + "
");
                        }
                    }
                }

Теперь повторите все те действия в результате которых появилась эта ошибка и вы увидите описание того, что не так с вашими объектами EF простым и понятным языком (в зависимости от локализации вашей ОС, конечно.

Я получаю следующую ошибку, когда пытаюсь update-database в шагах миграции (откройте окно консоли диспетчера пакетов и введите команду «обновить базу данных»)

System.Data.Entity.Validation.DbEntityValidationException: Ошибка проверки одного или нескольких объектов. Дополнительные сведения см. в описании свойства EntityValidationErrors.

Я добавляю новое поле в Movie класс

public class Movie
{
        public int ID { get; set; }
        [Required]
        [DisplayName("Name")]
        public string MovieName { get; set; }
        [Required]
        [DisplayName("Type")]
        public string MovieType { get; set; }
        [DisplayName("Year")]
        public int MovieProductionYear { get; set; }
        [Range(1, 5)]
        [DisplayName("Priority")]
        public int priority { get; set; }
        [DisplayName("NoOfWatches")]
        public int NumberOfWatches { get; set; }
        [DisplayName("isWatched")]
        public bool isWatched { get; set; }
        [Range(1, 10)]
        [DisplayName("IMDB")]
        public int IMDBRating { get; set; }
        [DisplayName("Available")]
        public bool Availability { get; set; }
        [StringLength(50)]
        [DisplayName("Comments")]
        public string Comments { get; set; }
        [DisplayName("Actor")]
        public string Actor { get; set; }
        [DataType(DataType.Date)]
        public DateTime ReleasedDate { get; set; }
    }

и добавить класс миграции для новых полей содержит эти методы вверх и вниз

public override void Up()
{
    AddColumn("dbo.Movies", "NumberOfWatches", c => c.Int(nullable: false));
    AddColumn("dbo.Movies", "ReleasedDate", c => c.DateTime(nullable: false));
}

public override void Down()
{
    DropColumn("dbo.Movies", "ReleasedDate");
    DropColumn("dbo.Movies", "NumberOfWatches");
}

Когда я удаляю два поля и обновляю базу данных, метод seed успешно работает

Какие-либо предложения?

Спасибо.

  • Remove From My Forums
  • Вопрос

  • Есть поле, которое должно быть в базе c ограничением «NOT NULL». В модели оно соответственно Required.

    Это поле нужно заполнить программно (не во View). Но из-за Required не проходит клиентская валидация.

    Как быть в этом случае?

Ответы

  • Вы должны передать/получить в View SomeViewModel:

            public ActionResult Edit(string id)
            {
                SomeModel someModel = EntityManager.Get<SomeModel>(id);
                return View(new SomeViewModel(someModel));
            }

    • Помечено в качестве ответа

      20 мая 2014 г. 11:25

  • Это псевдокод, для примера.

    Вы должны заменить EntityManager на тот тип, который отвечает в вашей программе за работу с данными.

  • )))))

    Вроде получилось. Посмотрите, правильно я понял суть?

        Public Class SomeModel
    
        	Public Sub SynchSomeModel(newViewModel As SomeViewModel)
               Me.Prop1 = newViewModel.Prop1 
          	   Me.Prop2 = newViewModel.Prop2
               Me.Prop3 = "Заполняем сами"
               Me.Prop4 = "Заполняем сами"
               Me.Prop5 = newViewModel.Prop5
            End Sub
        
            <Required>
            Public Property Prop1 As String
            
    	<Required>
            Public Property Prop2 As String
    
            <Required>
            Public Property Prop3 As String
    
            <Required>
            Public Property Prop4 As String
    
            <Required>
            Public Property Prop5 As String
    
        End Class
    
    
        Public Class SomeViewModel
    
            <Required>
            Public Property Prop1 As String
             
    	<Required>
            Public Property Prop2 As String
    
            <Required>
            Public Property Prop5 As String
    
        End Class
    
    
      'Контроллер
    
      ' GET: /Home/Create
       Function Create() As ActionResult
       	Return View(New SomeViewModel())
       End Function
    
      ' POST: /Home/Create
      <HttpPost()>
      Async Function Create(newViewModel As SomeViewModel) As Task(Of ActionResult)
    
                If ModelState.IsValid Then
                    Dim _someModel As New SomeModel
                    _someModel.SynchSomeModel(newViewModel)
    
                    db.SomeModels.Add(_someModel)
                    Await db.SaveChangesAsync()
    
                    Return RedirectToAction("Index")
                End If
                
                Return View(newViewModel)
      End Function
    
    'View
    
    @ModelType SomeViewModel
    ...

    Смущает, что такой огород приходится городить из-за такой мелочи ))

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А вот еще интересные материалы:

  • Яшка сломя голову остановился исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
  • Проверка почтового домена на ошибки
  • Проверка на ошибки микроразметки