3

I'm trying to discover what the specific validation errors are that's causing the validation exception when I update the database. I am reasonably sure that the culprit is the SaveChanges(). I think there's something wrong with one or more properties in one or more of my 3 classes. The only way of resolving the exception is to discover the validation error(s).

I'm a newbie when it comes to this way of debugging, though I'm experienced in several different languages. I've set a breakpoint where indicated so I can see the debug.writeline results, but two problems: it never stops at the breakpoint and I don't see "debug" in the output window dropdown.

What am I not understanding? Is there as better method of trapping validation errors?

Here is the full code in configuration.cs file.

namespace AlbumSong2.Migrations
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Data.Entity.Validation;
    using System.Diagnostics;
    using System.Linq;

    internal sealed class Configuration : DbMigrationsConfiguration<AlbumSong2.Model.AlbumDbContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
            //if (System.Diagnostics.Debugger.IsAttached == false)
            //    System.Diagnostics.Debugger.Launch();
        }

        protected override void Seed(AlbumSong2.Model.AlbumDbContext context)
        {
            //  This method will be called after migrating to the latest version.

            //  You can use the DbSet<T>.AddOrUpdate() helper extension method 
            //  to avoid creating duplicate seed data. E.g.
            //
            //    context.People.AddOrUpdate(
            //      p => p.FullName,
            //      new Person { FullName = "Andrew Peters" },
            //      new Person { FullName = "Brice Lambson" },
            //      new Person { FullName = "Rowan Miller" }
            //    );
            //
            context.Singers.AddOrUpdate(t => t.SingerName,
                new Singer() { SingerName = "Chuck Negron" },
                new Singer() { SingerName = "Cory Wells" },
                new Singer() { SingerName = "Dan Hutton" });
            context.SaveChanges();

            try
            {
                context.Albums.AddOrUpdate(t => t.AlbumName,
                    new Album()
                    {
                        AlbumName = "Three Dog Night",
                        AlbumTitle = "Seven Separate Fools",
                        Price = 15,
                        aLength = 45,
                        Year = "1972",
                        isUSA = true,
                        CurrentSingerId = 1
                    },
                    new Album()
                    {
                        AlbumName = "Steppenwolf",
                        AlbumTitle = "Cyan",
                        Price = 10,
                        aLength = 35,
                        Year = "1973",
                        isUSA = true,
                        CurrentSingerId = 2
                    },
                    new Album()
                    {
                        AlbumName = "Grand Funk Railroad",
                        AlbumTitle = "It Ain't Easy",
                        Price = 10,
                        aLength = 35,
                        Year = "1970",
                        isUSA = true,
                        CurrentSingerId = 3
                    });
                context.SaveChanges();
            }
            catch (DbEntityValidationException e)
            {
                foreach (var eve in e.EntityValidationErrors)
                {
                    Debug.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)
                    {
                        Debug.WriteLine("- Property: \"{0}\", Value: \"{1}\", Error: \"{2}\"",
                            ve.PropertyName, 
                            eve.Entry.CurrentValues.GetValue<object>(ve.PropertyName),
                            ve.ErrorMessage);
                    }
                }
                throw;
            }

            try
            { 
            context.Songs.AddOrUpdate(t => t.SongTitle,
                new Song() { SongTitle = "Black and White", sLength = 4, CurrentAlbumId = 1 },
                new Song() { SongTitle = "Let Me Seranade You", sLength = 3, CurrentAlbumId = 2 },
                new Song() { SongTitle = "Mama Told Me (Not To Come)", sLength = 3, CurrentAlbumId = 3 });
            context.SaveChanges();
            }
            catch (DbEntityValidationException e)
            {
                foreach (var eve in e.EntityValidationErrors)
                {
                    Debug.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)
                    {
                        Debug.WriteLine("- Property: \"{0}\", Value: \"{1}\", Error: \"{2}\"",
                            ve.PropertyName,
                            eve.Entry.CurrentValues.GetValue<object>(ve.PropertyName), 
                            ve.ErrorMessage);
                    }
                }
                throw;
            }

        }
    }
}

And the Album class follows:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace AlbumSong2
{
    //[Table("Albums")]
    public class Album
    {
        public int AlbumId { get; set; }
        [MinLength(5), MaxLength(25), Required]
        public string AlbumName { get; set; }
        [MinLength(5), MaxLength(25), Required]
        public string AlbumTitle { get; set; }
        public string Year { get; set; }
        [Range(10, 50)]
        public int aLength { get; set; }
        [Range(1, 15)]
        public double Price { get; set; }
        public bool isUSA { get; set; }

        //navigation property -> each Album has many Songs, indicating dependent (child) entity
        public List<Song> Songs { get; set; }

        //navigation property -> indicates parent table
        public Singer CurrentSinger { get; set; }

        [ForeignKey("CurrentSinger")]
        public int? CurrentSingerId { get; set; }


    }
}

And the song class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;


namespace AlbumSong2
{
    //[Table("Songs")]
    public class Song
    {
        public int SongId { get; set; }

        [MinLength(2), MaxLength(45)]
        [Required]
        public string SongTitle { get; set; }
        public int sLength { get; set; }

        //navigation property -> indicates parent table
        public Album CurrentAlbum { get; set; }

        [ForeignKey("CurrentAlbum")]
        public int CurrentAlbumId { get; set; }
    }
}

Finally, the singer class. (There is nothing wrong with the singer table in the database or the code. It's the other two I'm having a problem with):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace AlbumSong2
{
    //[Table("Singers")]
    public class Singer
    {
        public int SingerId { get; set; }

        [MinLength(5), MaxLength(25)]
        [Required]
        public string SingerName { get; set; }

        //navigation property -> each Singer has many Albums
        public List<Album> Albums { get; set; }
    }
}

Here's a screenshot of my VS program, showing the breakpoint and the validation error.

VS screenshot

2 Answers2

5

I've moved the try/catch routine from Configuration file to AlbumDbContext where I was able to successfully trap the error. Here's the code in AlbumDbContext file:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.Data.Entity.Validation;
using System.Text;
using System.Runtime.Remoting.Contexts;

namespace AlbumSong2.Model
{
    public class AlbumDbContext : DbContext
    {
        public AlbumDbContext() : base("AlbumDbConnection2") { }
        public IDbSet<Singer> Singers { get; set; }
        public IDbSet<Album> Albums { get; set; }
        public IDbSet<Song> Songs { get; set; }


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

And here's the output!

enter image description here

Problem solved.

0

If a Breakpoint isn´t reached, then you don´t use that function/method or that part of your function/method isn´t reached by your code.

A good debugging would also include stuff like NUnit-for bigger stuff. Or always doing a console window that acts as a log. There are plenty of packages for that I think. (To tell how important that message that is and if it has to be in the log)

Also maybe "throw" isn´t a good option. Maybe you could use a MessageBox (or the ConsoleLog) and print the exception e. Maybe that helps you.

Garamaru
  • 106
  • 1
  • 1
  • 11