Вопрос по entity-framework-4, entity-framework, asp.net-mvc-3 – Сначала код EF: как мне увидеть свойство EntityValidationErrors из консоли пакета nuget?

122

Я в недоумении по этому поводу:

Я определил мои классы для подхода, основанного на коде структуры сущностей (4.1.3). Все было хорошо (я создавал таблицы и т. Д.), Пока я не начал сеять.

Теперь, когда я делаю

Add-Migration "remigrate" ; Update-Database;

Я получаю сообщение об ошибке на консоли пакета "Проверка не удалась для одного или нескольких объектов. См. «EntityValidationErrors»; свойство для более подробной информации. & quot;

У меня есть точка останова в моем методе Seed (), но из-за того, что я запускаю это на консоли, когда проект не запущен, я понятия не имею, как добраться до деталей (PS - я видел потокОшибка проверки для одного или нескольких объектов при сохранении изменений в базе данных SQL Server с использованием Entity Framework который показывает, как я могу видеть собственность.)

Я знаю, что у моего метода Seed () есть проблема, потому что, если я поместил возврат сразу после вызова метода, ошибка исчезнет. Итак, как мне установить точку останова, чтобы я мог видеть, что такое ошибка проверки? Какая-то потеряна. Или есть какой-то другой способ отследить его в консоли nuget ??

Я думаю, что вы могли бы запустить миграцию программно, а затем перехватить исключение и повторить ошибки. Это не идеально, но может дать вам необходимую информацию. Pawel
Разочарование, когда неправильный ответ находится в верхней части ответов и получает весь кредит. Место, где StackOverflow явно не хватает! jwize
Быстрое обновление: я решил свою проблему, систематически отслеживая каждую переменную в моем методе, пока не нашел причину ошибки. Однако мне все еще хотелось бы знать ответ на мой вопрос, так как это было бы намного быстрее! jeremy
Если вы используетеEntity Framework Вы можете посмотреть мой ответ наSolution for “Validation failed for one or more entities. See 'EntityValidationErrors' property for more details, Надеюсь это поможет... Murat Yıldız

Ваш Ответ

6   ответов
3

спасибо, что указал мне правильный путь (имел ту же проблему) ниже - альтернатива без оболочки, это работало для меня в начальном методе конфигурации миграции:

 Protected Overrides Sub Seed(context As NotificationContext)

        Try
            context.System.AddOrUpdate(
               Function(c) c.SystemName,
                New E_NotificationSystem() With {.SystemName = "System1"},
                New E_NotificationSystem() With {.SystemName = "System2"},
                New E_NotificationSystem() With {.SystemName = "System3"})

            context.SaveChanges()

        Catch ex As DbEntityValidationException

            Dim sb As New StringBuilder

            For Each failure In ex.EntityValidationErrors

                sb.AppendFormat("{0} failed validation" & vbLf, failure.Entry.Entity.[GetType]())

                For Each [error] In failure.ValidationErrors
                    sb.AppendFormat("- {0} : {1}", [error].PropertyName, [error].ErrorMessage)
                    sb.AppendLine()
                Next
            Next

            Throw New Exception(sb.ToString())

        End Try
End Sub

Затем смог увидеть исключение в консоли диспетчера пакетов. Надеюсь, это кому-нибудь поможет.

210

поместив функцию-обертку в класс Configuration в метод Seed, и заменил вызовы наSaveChanges с вызовами к моей функции вместо. Эта функция просто перечислит ошибки в пределахEntityValidationErrors сбор и повторное создание исключения, в котором в сообщении об исключении перечислены отдельные проблемы. Это заставляет вывод отображаться в консоли диспетчера пакетов NuGet.

Код следует:

/// <summary>
/// Wrapper for SaveChanges adding the Validation Messages to the generated exception
/// </summary>
/// <param name="context">The context.</param>
private void SaveChanges(DbContext context) {
    try {
        context.SaveChanges();
    } catch (DbEntityValidationException ex) {
        StringBuilder sb = new StringBuilder();

        foreach (var failure in ex.EntityValidationErrors) {
            sb.AppendFormat("{0} failed validation\n", failure.Entry.Entity.GetType());
            foreach (var error in failure.ValidationErrors) {
                sb.AppendFormat("- {0} : {1}", error.PropertyName, error.ErrorMessage);
                sb.AppendLine();
            }
        }

        throw new DbEntityValidationException(
            "Entity Validation Failed - errors follow:\n" + 
            sb.ToString(), ex
        ); // Add the original exception as the innerException
    }
}

Просто замените звонки наcontext.SaveChanges() сSaveChanges(context) в вашем методе семени.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededpublic override int SaveChanges()Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded jeremy
4

мне пришлось добавить context.SaveChanges (); для того, чтобы он работал для меня, как показано ниже.

try
{
    byte[] bytes = System.IO.File.ReadAllBytes(@"C:\Users\sheph_000\Desktop\Rawr.png");
    Console.WriteLine(bytes);

    context.BeverageTypes.AddOrUpdate(
        x => x.Name,
        new AATPos.DAL.Entities.BeverageType { ID = 1, Name = "Sodas" }
        );

    context.Beverages.AddOrUpdate(
        x => x.Name,
        new AATPos.DAL.Entities.Beverage { ID = 1, Name = "Coke", BeverageTypeID = 1, ImageData = bytes, IsStocked = true, StockLevel = 10, Price = 10.00M, ImageMimeType = "test" },
        new AATPos.DAL.Entities.Beverage { ID = 2, Name = "Fanta", BeverageTypeID = 1, ImageData = bytes, IsStocked = true, StockLevel = 10, Price = 10.00M, ImageMimeType = "test" },
        new AATPos.DAL.Entities.Beverage { ID = 3, Name = "Sprite", BeverageTypeID = 1, ImageData = bytes, IsStocked = true, StockLevel = 10, Price = 10.00M, ImageMimeType = "test" },
        new AATPos.DAL.Entities.Beverage { ID = 4, Name = "Cream Soda", BeverageTypeID = 1, ImageData = bytes, IsStocked = true, StockLevel = 10, Price = 10.00M, ImageMimeType = "test" },
        new AATPos.DAL.Entities.Beverage { ID = 5, Name = "Pepsi", BeverageTypeID = 1, ImageData = bytes, IsStocked = true, StockLevel = 10, Price = 10.00M, ImageMimeType = "test" }
        );

    context.SaveChanges();
}
catch (System.Data.Entity.Validation.DbEntityValidationException ex)
{
    var sb = new System.Text.StringBuilder();
    foreach (var failure in ex.EntityValidationErrors)
            {
                sb.AppendFormat("{0} failed validation", failure.Entry.Entity.GetType());
        foreach (var error in failure.ValidationErrors)
                {
            sb.AppendFormat("- {0} : {1}", error.PropertyName, error.ErrorMessage);
            sb.AppendLine();
                }
            }

    throw new Exception(sb.ToString());
}
35

  public static int SaveChangesWithErrors(this DbContext context)
    {
        try
        {
            return context.SaveChanges();
        }
        catch (DbEntityValidationException ex)
        {
            StringBuilder sb = new StringBuilder();

            foreach (var failure in ex.EntityValidationErrors)
            {
                sb.AppendFormat("{0} failed validation\n", failure.Entry.Entity.GetType());
                foreach (var error in failure.ValidationErrors)
                {
                    sb.AppendFormat("- {0} : {1}", error.,PropertyName, error.ErrorMessage);
                    sb.AppendLine();
                }
            }

            throw new DbEntityValidationException(
                "Entity Validation Failed - errors follow:\n" +
                sb.ToString(), ex
            ); // Add the original exception as the innerException
        }
    }

Звоните так:

context.SaveChangesWithErrors();
110

Extend Your DBContext Class Already With a Partial Class Definition!

Если вы посмотрите на определение класса для вашего DbContext, это будет что-то вроде следующего:

// DatabaseContext.cs   -- This file is auto generated and thus shouldn't be changed. 
public partial class [DatabaseContextName] : DbContext { ... }

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

// partialDatabaseContext.cs  -- you can safely make changes 
// that will not be overwritten in here.
public partial class [DatabaseContextName] : DbContext { // Override defaults here } 

Вся идея с частичными занятиями--did you notice the DbContext is a partial class-- является то, что вы можете расширить сгенерированный класс (или организовать классы в несколько файлов), и в нашем случае мы также хотимoverride SaveChanges метод из частичного класса, который добавляет кDbContext.

Таким образом, мы можем получить информацию об отладке ошибок из всех существующих вызовов DbContext / SaveChanges везде и не нужно менять код Seed или код разработки вообще.

Это то, что я бы сделал (NOTE разница в том, что я просто переопределяю метод SaveChanges в нашем собственномDbContext частичный класс,NOT THE GENERATED ONE). Кроме того, убедитесь, что ваш частичный класс используетcorrect namespace или вы будете биться головой о стену.

public partial class Database : DbContext
{
    public override int SaveChanges()
    {
        try
        {
            return base.SaveChanges();
        }
        catch (DbEntityValidationException ex)
        {
            var sb = new StringBuilder();

            foreach (var failure in ex.EntityValidationErrors)
            {
                sb.AppendFormat("{0} failed validation\n", failure.Entry.Entity.GetType());
                foreach (var error in failure.ValidationErrors)
                {
                    sb.AppendFormat("- {0} : {1}", error.PropertyName, error.ErrorMessage);
                    sb.AppendLine();
                }
            }

            throw new DbEntityValidationException(
                "Entity Validation Failed - errors follow:\n" +
                sb.ToString(), ex
                ); // Add the original exception as the innerException
        }
    }
}
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
0

elf after lot of thinking;

I use reverse engineering method to catch the problem out of Over 80 + Model Classes;

1> Made copy of dbcontext, changing the name (I add "1" at end and make respective changes in class constructor and initialization etc.

Old:
 
>public class AppDb : IdentityDbContext<ApplicationUser>
>     
> {
> public AppDb(): base("DefaultConnection", throwIfV1Schema: false)
> {
> 
> }
>     
> public static AppDb Create()
>{
>return new AppDb();
>} 

**New:**

>public class AppDb1 : IdentityDbContext<ApplicationUser>
>{
>public AppDb1()
>: base("DefaultConnection", throwIfV1Schema: false)
>{
>}
> 
>public static AppDb1 Create()
> {
> return new AppDb1();
>  }`

...
2> Make changes to Codefirst Migration Configuration from Old DbContext to my new Context.

> internal sealed class Configuration :
> DbMigrationsConfiguration<DAL.AppDb1> { public Configuration() {
> AutomaticMigrationsEnabled = false; }    protected override void
> Seed(DAL.AppDb1 context) {`

3> Comment the Dbsets in new DbContext which was doubt.
4> Apply update migration if succeeded the probelm lye in Commented section.
5> if not then commented section is clear of bug clear.
6> repeat the (4) until found the right place of bug.
7> Happy Codding

Error: User Rate Limit Exceeded

Похожие вопросы