Sequence contains more than one element

Easiest way to debug Seed-method in Code-first migrations in Entity Framework

This post was most recently updated on March 27th, 2019.

Reading Time: 4 minutes.

This post describes the easiest way to debug the issues that may stop your Seed-method in Configuration.cs from going through. This problem concerns typically your ASP.NET MVC projects, either on .NET Framework or .NET Core – the same basic idea should work for both situations.

The solution here shows you, how you can get a little bit more information out of the process, without attaching the debugger (there’s another blog post for that: How to launch the visual studio debugger from code/)

Description

Entity Framework’s code-first migration’s are a beautiful and easy way of managing database schema changes and populating some preliminary data there. Personally I also sometimes use the method for adding some enrichment to data or or custom property values mapping that would otherwise require an additional/external console program.

Problem: running the Seed-method is by default undebuggable

Okay – so seeding data is cool. You do that within your Configuration.cs -file when running Update-Database to insert some default or baseline data to your database.

That’s fine and dandy, but debugging the issues in the function while running Update-Database is NOT so cool. You can’t run the Seed-method with debugger turned on. Hence, when you run into issues, you only get the stacktrace and exception message – and that’s not always that informative.

In my other blog post, I describe how you CAN in fact debug the Seed-method, by launcing a debugger instance manually from the method itself. See the other solution here:

This blog post shows an alternative to that – you can also modify the error messages thrown during the Seed method!

See this:

update-database
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
No pending explicit migrations.
Running Seed method.
System.InvalidOperationException: Sequence contains more than one element
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
   at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.<getelementfunction>b__2[TResult](IEnumerable`1 sequence)
   at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot)
   at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[TResult](Expression expression)
   at System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](Expression expression)
   at System.Linq.Queryable.SingleOrDefault[TSource](IQueryable`1 source, Expression`1 predicate)
   at System.Data.Entity.Migrations.DbSetMigrationsExtensions.AddOrUpdate[TEntity](DbSet`1 set, IEnumerable`1 identifyingProperties, InternalSet`1 internalSet, TEntity[] entities)
   at System.Data.Entity.Migrations.DbSetMigrationsExtensions.AddOrUpdate[TEntity](IDbSet`1 set, Expression`1 identifierExpression, TEntity[] entities)
   at ....Migrations.Configuration.Seed(ApplicationDbContext db) in C:\...\Migrations\Configuration.cs:line 345
   at System.Data.Entity.Migrations.DbMigrationsConfiguration`1.OnSeed(DbContext context)
   at System.Data.Entity.Migrations.DbMigrator.SeedDatabase()
   at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.SeedDatabase()
   at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
   at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
   at System.Data.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration)
   at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClassc.<update>b__b()
   at System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
   at System.Data.Entity.Migrations.Infrastructure.MigratorBase.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
   at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
   at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration)
   at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.Run()
   at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
   at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
   at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner)
   at System.Data.Entity.Migrations.Design.ToolingFacade.Update(String targetMigration, Boolean force)
   at System.Data.Entity.Migrations.UpdateDatabaseCommand.<>c__DisplayClass2.<.ctor>b__0()
   at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)
Sequence contains more than one element.

Okay, so “Sequence contains more than one element”. Cool. I’m probably failing an AddOrUpdate-call somewhere, but I hate going through the exception to find the Configuration.cs:345 (or similar) row that actually tells where the exception was, when I could have the exception tell me what went wrong. Unfortunately, the exception just shows me the message of the thrown exception – which is NOT descriptive.

Oh, but wait: There is a solution!

Solution

By wrapping the whole stuff in a try-catch -block, catching the thrown exception, wrapping a new exception with a custom message around it and including the original one as internal exception, we get the data from the original exception AND our custom message – which in my case tells how far in the Seed-method (or just in which part of seeding / mapping the data we are in) we’ve proceeded. You can even make it tell the line where we’ve gotten to!

So, in my Configuration.cs class (in Migrations), I have first this:

internal class Configuration : DbMigrationsConfiguration<applicationdbcontext>
    {
        private bool _debug = false;
 
        private string _customExceptionMessage = "";
 
...

Then, further down the line when seeding my data, I have these little calls:

db.Companies.AddOrUpdate(p =&gt; p.CompanyIdentifier,
	new Company
	{
		...
	},
	new Company
	{
		...
	}
);
db.SaveChanges();
_customExceptionMessage += "Companies saved ok;";

This goes on for a while, but I’ve wrapped the whole method in a try-catch, like below:

/// <summary>
/// This method will be called after migrating to the latest version.
/// </summary>
/// <param name="db">
protected override void Seed(ApplicationDbContext db)
{
	try
	{
		_customExceptionMessage += "Running Seed method in Configuration.cs;";
 
		db.Companies.AddOrUpdate(p =&gt; p.CompanyIdentifier,
			new Company
			{
				...
			},
			new Company
			{
				...
			}
		);
		db.SaveChanges();
		_customExceptionMessage += "Companies saved ok;"
 
		... 
	}
	catch (Exception ex)
	{
		Exception ex2 = new Exception(_customExceptionMessage, ex);
 
		throw ex2;
	}
}

Now the exception in the Package Manager Console will be something like this:

// Omitted for clarity
...
   at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
   at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration)
   at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.Run()
   at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
   at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
   at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner)
   at System.Data.Entity.Migrations.Design.ToolingFacade.Update(String targetMigration, Boolean force)
   at System.Data.Entity.Migrations.UpdateDatabaseCommand.<>c__DisplayClass2.<.ctor>b__0()
   at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)
Running Seed method in Configuration.cs;Companies saved ok;User added to company ok;Contacts saved ok;

So, now you get this:

Running Seed method in Configuration.cs;Companies saved ok;User added to company ok;Contacts saved ok;

To let you know how far you got in the execution.

This is, at least to me, a small improvement. Pretty? Ha, no. Much faster than launching a debugger? Yes!

Also, very hack-ish, but better than the normal functionality. And combined with launching the debugger from the code (as described here), quite an improvement over just getting a stacktrace.

Antti K. Koskela

Antti Koskela is a proud digital native nomadic millennial full stack developer (is that enough funny buzzwords? That's definitely enough funny buzzwords!), who works as a Solutions Architect for Valo Intranet, the product that will make you fall in love with your intranet. Working with the global partner network, he's responsible for the success of Valo deployments happening all around the world.

He's been a developer from 2004 (starting with PHP and Java), and he's been bending and twisting SharePoint into different shapes since MOSS. Nowadays he's not only working on SharePoint, but also on .NET projects, Azure, Office 365 and a lot of other stuff.

This is his personal professional (e.g. professional, but definitely personal) blog.
mm

2
Leave a Reply

avatar
5000
2 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
0 Comment authors
Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
trackback

[…] very little about the actual issue, and since debugging code-first migrations is kind of difficult (see the best tips for that here!), it’s cumbersome to […]

trackback

[…] very little about the actual issue, and since debugging code-first migrations is kind of difficult (see the best tips for that here!), it’s cumbersome to […]