Skip to content

Commit

Permalink
Merge pull request #4 from dpaquette/ExceptionHandling
Browse files Browse the repository at this point in the history
Exception handling
  • Loading branch information
dpaquette committed Feb 2, 2015
2 parents b00af25 + 0f1138b commit a19f804
Show file tree
Hide file tree
Showing 10 changed files with 158 additions and 14 deletions.
Binary file added package/EntityFramework.Seeder.EF6.0.3.0.nupkg
Binary file not shown.
Binary file added package/EntityFramework.Seeder.EF6.0.3.1.nupkg
Binary file not shown.
Binary file added package/EntityFramework.Seeder.EF6.0.3.2.nupkg
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CodeNotRight,NameAlsoNotRight
AT,Austria
AU,Australia
CA,Canada
US,United States
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
<Compile Include="Domain\Country.cs" />
<Compile Include="Domain\CountryContext.cs" />
<Compile Include="Domain\ProvinceState.cs" />
<Compile Include="when_an_error_occurs_while_seeding_a_dbset.cs" />
<Compile Include="when_seeding_an_empty_db_set_from_a_file.cs" />
<Compile Include="when_seeding_an_empty_db_set_from_a_resource.cs" />
<Compile Include="when_seeding_a_dbset_with_related_entites.cs" />
Expand All @@ -98,6 +99,9 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<EmbeddedResource Include="ProvinceStatesResource.csv" />
<Content Include="CountriesFileWithErrors.csv">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using System;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using EntityFramework.Seeder.EF6.Tests.Domain;
using Given.Common;
using Given.NUnit;
using NUnit.Framework;

namespace EntityFramework.Seeder.EF6.Tests
{
[Story(AsA = "developer",
IWant = "see exception details",
SoThat = "I can diagnose errors that might happen while seeding a dbset")]
public class while_an_error_occurs_while_seeding_a_dbset : Scenario
{
public static CountryContext _context;

given an_empty_context = () =>
{
_context = new CountryContext();
_context.DeleteAll();
};


[then]
[ExpectedException(typeof(Exception))]
public void when_seeding_from_a_file_with_unmapped_columns()
{
_context.Countries.SeedFromFile("CountriesFileWithErrors.csv", c => c.Code);
}

[then]
public void the_exception_should_be_serializable()
{
Exception exception = null;
try
{
_context.Countries.SeedFromFile("CountriesFileWithErrors.csv", c => c.Code);
}
catch (Exception ex)
{
exception = ex;
}

Assert.IsNotNull(exception);

string exceptionToString = exception.ToString();

// Round-trip the exception: Serialize and de-serialize with a BinaryFormatter
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
// "Save" object state
bf.Serialize(ms, exception);

// Re-use the same stream for de-serialization
ms.Seek(0, 0);

// Replace the original exception with de-serialized one
exception = (Exception)bf.Deserialize(ms);
}

// Double-check that the exception message and stack trace (owned by the base Exception) are preserved
Assert.AreEqual(exceptionToString, exception.ToString(), "ex.ToString()");
}

[TestFixtureTearDown]
public void TearDown()
{
_context.Dispose();
}
}
}
34 changes: 34 additions & 0 deletions src/EntityFramework.Seeder.EF6/EFSeederException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace EntityFramework.Seeder
{
/// <summary>
/// Represents an exception that has occurred while seeding a dbset.
/// Wraps the underlying exception and is serializable so that the exception message can be
/// properly displayed in the package manager console in Visual Studio
/// </summary>
[Serializable]
public class EfSeederException : Exception, ISerializable
{
public EfSeederException()
{
}

public EfSeederException(string message) : base(message)
{
}

public EfSeederException(string message, Exception innerException) : base(message, innerException)
{
}

protected EfSeederException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="CsvColumnMapping.cs" />
<Compile Include="EFSeederException.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Seeder.cs" />
</ItemGroup>
Expand Down
6 changes: 3 additions & 3 deletions src/EntityFramework.Seeder.EF6/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("EntityFramework.Seeder")]
[assembly: AssemblyCopyright("Copyright © 2014")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

Expand All @@ -32,5 +32,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.2.1.0")]
[assembly: AssemblyFileVersion("0.2.1.0")]
[assembly: AssemblyVersion("0.3.2.0")]
[assembly: AssemblyFileVersion("0.3.2.0")]
48 changes: 37 additions & 11 deletions src/EntityFramework.Seeder.EF6/Seeder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,22 @@ namespace EntityFramework.Seeder
/// </summary>
public static class Seeder
{
static Seeder()
{
AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly;
}

private static Assembly ResolveAssembly(object sender, ResolveEventArgs args)
{
if (new AssemblyName(args.Name).Name == "EntityFramework.Seeder.EF6")
{
return typeof (Seeder).Assembly;
}

return null;

}

/// <summary>
/// Seeds a DBSet from a CSV file that will be read from the specified stream
/// </summary>
Expand All @@ -23,23 +39,33 @@ public static class Seeder
/// <param name="additionalMapping">Any additonal complex mappings required</param>
public static void SeedFromStream<T>(this IDbSet<T> dbSet, Stream stream, Expression<Func<T, object>> identifierExpression, params CsvColumnMapping<T>[] additionalMapping) where T : class
{
using (StreamReader reader = new StreamReader(stream))
try
{
CsvReader csvReader = new CsvReader(reader);
var map = csvReader.Configuration.AutoMap<T>();
map.ReferenceMaps.Clear();
csvReader.Configuration.RegisterClassMap(map);
csvReader.Configuration.WillThrowOnMissingField = false;
while (csvReader.Read())
using (StreamReader reader = new StreamReader(stream))
{
var entity= csvReader.GetRecord<T>();
foreach (CsvColumnMapping<T> csvColumnMapping in additionalMapping)
CsvReader csvReader = new CsvReader(reader);
var map = csvReader.Configuration.AutoMap<T>();
map.ReferenceMaps.Clear();
csvReader.Configuration.RegisterClassMap(map);
csvReader.Configuration.WillThrowOnMissingField = false;
while (csvReader.Read())
{
csvColumnMapping.Execute(entity, csvReader.GetField(csvColumnMapping.CsvColumnName));
var entity = csvReader.GetRecord<T>();
foreach (CsvColumnMapping<T> csvColumnMapping in additionalMapping)
{
csvColumnMapping.Execute(entity, csvReader.GetField(csvColumnMapping.CsvColumnName));
}
dbSet.AddOrUpdate(identifierExpression, entity);
}
dbSet.AddOrUpdate(identifierExpression, entity);
}
}
catch (Exception ex)
{
string message = string.Format("Error Seeding DbSet<{0}>: {1}", dbSet.GetType().GenericTypeArguments[0].FullName, ex.ToString());
Exception innerException = ex.GetType().IsSerializable ? ex : null;
//Unfortunately I need to use a root exception here as this is the only way for the Update-Database powershell script to properly report the error
throw new Exception(message, innerException);
}
}

/// <summary>
Expand Down

0 comments on commit a19f804

Please sign in to comment.