Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity framework throws exception while executing UPDATE statement

I have an EF6 powered program that crashes on an UPDATE statement, when running for the first time. I tried renaming the columns via data annotations (I didn't test fluid API, since it should result in the same database). I also looked at the class visibilities, but they didn't change since the last time the program worked and thus can be ruled out. I've looked at it for the better part of a day, but cannot find the error. The database looks sound to me and the code compiles without problem. Also any update-database statements are executed without an exception.

Here is the stack-trace:

System.Data.DataException was unhandled by user code
  HResult=-2146233087
  Message=An exception occurred while initializing the database. See the InnerException for details.
  Source=EntityFramework
  StackTrace:
       bei System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action)
       bei System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization()
       bei System.Data.Entity.Internal.LazyInternalContext.<InitializeDatabase>b__4(InternalContext c)
       bei System.Data.Entity.Internal.RetryAction`1.PerformAction(TInput input)
       bei System.Data.Entity.Internal.LazyInternalContext.InitializeDatabaseAction(Action`1 action)
       bei System.Data.Entity.Internal.LazyInternalContext.InitializeDatabase()
       bei System.Data.Entity.Internal.InternalContext.Initialize()
       bei System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
       bei System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
       bei System.Data.Entity.Internal.Linq.InternalSet`1.Include(String path)
       bei System.Data.Entity.Infrastructure.DbQuery`1.Include(String path)
       bei System.Data.Entity.QueryableExtensions.Include[T](IQueryable`1 source, String path)
       bei System.Data.Entity.QueryableExtensions.Include[T,TProperty](IQueryable`1 source, Expression`1 path)
       bei RpgTools.Characters.CharacterRepository.FindAll() in e:\Users\Robert\Documents\Visual Studio 2013\Projects\RpgTools\Modules\Characters\CharacterRepository.cs:Zeile 88.
       bei RpgTools.CharacterPresenter.ViewModels.CharactersViewModel.LoadCharacters() in e:\Users\Robert\Documents\Visual Studio 2013\Projects\RpgTools\Modules\CharacterPresenter\ViewModels\CharactersViewModel.cs:Zeile 169.
  InnerException: System.Data.Entity.Infrastructure.DbUpdateException
       HResult=-2146233087
       Message=An error occurred while updating the entries. See the inner exception for details.
       Source=EntityFramework
       StackTrace:
            bei System.Data.Entity.Internal.InternalContext.SaveChanges()
            bei System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
            bei System.Data.Entity.DbContext.SaveChanges()
            bei System.Data.Entity.Migrations.DbMigrator.SeedDatabase()
            bei System.Data.Entity.Migrations.Infrastructure.MigratorBase.SeedDatabase()
            bei System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
            bei System.Data.Entity.Migrations.Infrastructure.MigratorBase.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
            bei System.Data.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration)
            bei System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClassc.<Update>b__b()
            bei System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
            bei System.Data.Entity.Migrations.Infrastructure.MigratorBase.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
            bei System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
            bei System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update()
            bei System.Data.Entity.MigrateDatabaseToLatestVersion`2.InitializeDatabase(TContext context)
            bei System.Data.Entity.Internal.InternalContext.<>c__DisplayClassf`1.<CreateInitializationAction>b__e()
            bei System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action)
       InnerException: System.Data.Entity.Core.UpdateException
            HResult=-2146233087
            Message=An error occurred while updating the entries. See the inner exception for details.
            Source=EntityFramework
            StackTrace:
                 bei System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()
                 bei System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.<Update>b__2(UpdateTranslator ut)
                 bei System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update[T](T noChangesResult, Func`2 updateFunction)
                 bei System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update()
                 bei System.Data.Entity.Core.Objects.ObjectContext.<SaveChangesToStore>b__35()
                 bei System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
                 bei System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction)
                 bei System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass2a.<SaveChangesInternal>b__27()
                 bei System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
                 bei System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions options, Boolean executeInExistingTransaction)
                 bei System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions options)
                 bei System.Data.Entity.Internal.InternalContext.SaveChanges()
            InnerException: System.Data.SqlClient.SqlException
                 HResult=-2146232060
                 Message=The UPDATE statement conflicted with the FOREIGN KEY constraint "FK_Characters.Characters_Characters.Appearances_AppearanceId". The conflict occurred in database "RpgTools", table "Characters.Appearances", column 'Id'.
The statement has been terminated.
                 Source=.Net SqlClient Data Provider
                 ErrorCode=-2146232060
                 Class=16
                 LineNumber=1
                 Number=547
                 Procedure=""
                 Server=(LocalDb)\mssqllocaldb
                 State=0
                 StackTrace:
                      bei System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
                      bei System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
                      bei System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
                      bei System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
                      bei System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
                      bei System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
                      bei System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
                      bei System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite)
                      bei System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
                      bei System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<NonQuery>b__0(DbCommand t, DbCommandInterceptionContext`1 c)
                      bei System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
                      bei System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.NonQuery(DbCommand command, DbCommandInterceptionContext interceptionContext)
                      bei System.Data.Entity.Internal.InterceptableDbCommand.ExecuteNonQuery()
                      bei System.Data.Entity.Core.Mapping.Update.Internal.DynamicUpdateCommand.Execute(Dictionary`2 identifierValues, List`1 generatedValues)
                      bei System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()
                 InnerException: 

Here is the method that throws the exception. The exception is thrown on at the include statement. I might add, that the class for the following two methods is internal sealed

/// <inheritdoc />
public IDictionaryRange<Guid, Character> FindAll()
{
    IDataContainer<ICollection<CharacterItem>> data = this.CreateContainer<ICollection<CharacterItem>>(
        this.Characters.Include(c => c.Appearance).Include(c => c.Metadata).ToList(),
        this.Culture);

        return this.bulkReadConverter.Convert(data);
}

private IDataContainer<TData> CreateContainer<TData>(TData data, CultureInfo culture = null, DateTimeOffset? date = null)
{
    return new DataContainer<TData>
    {
        Content = data,
        Culture = culture,
        Date = date
    };
}

These are the classes that represent my data:

[Table("Character")]
internal class CharacterItem
{
    [Key]
    public Guid Id { get; set; }

    public string Name { get; set; }

    public string Nickname { get; set; }

    public string Title { get; set; }

    public string Description { get; set; }

    public string Biography { get; set; }

    public string Motto { get; set; }

    public int Age { get; set; }

    public Guid PortraitsId { get; set; }

    public PortraitItem Portrait { get; set; }

    public Guid MetadataId { get; set; }

    public CharacterMetadataItem Metadata { get; set; }

    public Guid AppearancesId { get; set; }

    public AppearanceItem Appearance { get; set; }

    public Guid OriginId { get; set; }
}

[Table("Appearances")]
internal sealed class AppearanceItem
{
    [Key]
    public Guid Id { get; set; }

    public Genders Gender { get; set; }

    public int Height { get; set; }

    public int Weight { get; set; }

    public string SkinColour { get; set; }

    public string EyeColour { get; set; }

    public string SpecialFeatures { get; set; }

    public string HairColour { get; set; }

    public string LipColour { get; set; }
}

And here are the SQL statements for the DB schema.

CREATE TABLE [Characters].[Character] (
    [Id]            UNIQUEIDENTIFIER NOT NULL,
    [Name]          NVARCHAR (MAX)   NULL,
    [Nickname]      NVARCHAR (MAX)   NULL,
    [Title]         NVARCHAR (MAX)   NULL,
    [Description]   NVARCHAR (MAX)   NULL,
    [Biography]     NVARCHAR (MAX)   NULL,
    [Motto]         NVARCHAR (MAX)   NULL,
    [Age]           INT              NOT NULL,
    [PortraitsId]   UNIQUEIDENTIFIER NOT NULL,
    [MetadataId]    UNIQUEIDENTIFIER NOT NULL,
    [AppearancesId] UNIQUEIDENTIFIER NOT NULL,
    [OriginId]      UNIQUEIDENTIFIER NOT NULL,
    [Appearance_Id] UNIQUEIDENTIFIER NULL,
    [Portrait_Id]   UNIQUEIDENTIFIER NULL,
    CONSTRAINT [PK_Characters.Character] PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [FK_Characters.Character_Characters.Appearances_Appearance_Id] FOREIGN KEY ([Appearance_Id]) REFERENCES [Characters].[Appearances] ([Id]),
    CONSTRAINT [FK_Characters.Character_Characters.Metadata_MetadataId] FOREIGN KEY ([MetadataId]) REFERENCES [Characters].[Metadata] ([Id]) ON DELETE CASCADE,
    CONSTRAINT [FK_Characters.Character_Characters.Portraits_Portrait_Id] FOREIGN KEY ([Portrait_Id]) REFERENCES [Characters].[Portraits] ([Id])
);


GO
CREATE NONCLUSTERED INDEX [IX_MetadataId]
    ON [Characters].[Character]([MetadataId] ASC);


GO
CREATE NONCLUSTERED INDEX [IX_Appearance_Id]
    ON [Characters].[Character]([Appearance_Id] ASC);


    GO
    CREATE NONCLUSTERED INDEX [IX_Portrait_Id]
        ON [Characters].[Character]([Portrait_Id] ASC);

CREATE TABLE [Characters].[Appearances] (
    [Id]              UNIQUEIDENTIFIER NOT NULL,
    [Gender]          INT              NOT NULL,
    [Height]          INT              NOT NULL,
    [Weight]          INT              NOT NULL,
    [SkinColour]      NVARCHAR (MAX)   NULL,
    [EyeColour]       NVARCHAR (MAX)   NULL,
    [SpecialFeatures] NVARCHAR (MAX)   NULL,
    [HairColour]      NVARCHAR (MAX)   NULL,
    [LipColour]       NVARCHAR (MAX)   NULL,
    CONSTRAINT [PK_Characters.Appearances] PRIMARY KEY CLUSTERED ([Id] ASC)
);

As per suggestion of John Castleman I changed the Schema initialisation, which was previously done by FluidAPI to DataAnnotations. Then I added another migration and applied another update-database now I get an error when I run the command, not just when starting the program. Below is the error and my migrations:

This is the stack trace with the -verbose switch enabled. I had to delete the old one, since I reached the character limit.

Using StartUp project 'Main'.
Using NuGet project 'Characters'.
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
Target database is: 'RpgTools' (DataSource: (LocalDb)\mssqllocaldb, Provider: System.Data.SqlClient, Origin: Configuration).
No pending explicit migrations.
Running Seed method.
System.Data.Entity.Infrastructure.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.Entity.Core.UpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.SqlClient.SqlException: The UPDATE statement conflicted with the FOREIGN KEY constraint "FK_Characters.Character_Characters.Metadata_MetadataId". The conflict occurred in database "RpgTools", table "Characters.Metadata", column 'Id'.
The statement has been terminated.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
   at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite)
   at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<NonQuery>b__0(DbCommand t, DbCommandInterceptionContext`1 c)
   at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.NonQuery(DbCommand command, DbCommandInterceptionContext interceptionContext)
   at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteNonQuery()
   at System.Data.Entity.Core.Mapping.Update.Internal.DynamicUpdateCommand.Execute(Dictionary`2 identifierValues, List`1 generatedValues)
   at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()
   --- End of inner exception stack trace ---
   at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()
   at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.<Update>b__2(UpdateTranslator ut)
   at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update[T](T noChangesResult, Func`2 updateFunction)
   at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update()
   at System.Data.Entity.Core.Objects.ObjectContext.<SaveChangesToStore>b__35()
   at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
   at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction)
   at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass2a.<SaveChangesInternal>b__27()
   at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
   at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions options, Boolean executeInExistingTransaction)
   at System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions options)
   at System.Data.Entity.Internal.InternalContext.SaveChanges()
   --- End of inner exception stack trace ---
   at System.Data.Entity.Internal.InternalContext.SaveChanges()
   at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
   at System.Data.Entity.DbContext.SaveChanges()
   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)
An error occurred while updating the entries. See the inner exception for details.

Migrations:

public partial class v0_1_0 : DbMigration
{
    public override void Up()
    {
        CreateTable(
            "Characters.Character",
            c => new
                {
                    Id = c.Guid(nullable: false),
                    Name = c.String(),
                    Nickname = c.String(),
                    Title = c.String(),
                    Description = c.String(),
                    Biography = c.String(),
                    Motto = c.String(),
                    Age = c.Int(nullable: false),
                    PortraitsId = c.Guid(nullable: false),
                    MetadataId = c.Guid(nullable: false),
                    AppearancesId = c.Guid(nullable: false),
                    OriginId = c.Guid(nullable: false),
                    Appearance_Id = c.Guid(),
                    Portrait_Id = c.Guid(),
                })
            .PrimaryKey(t => t.Id)
            .ForeignKey("Characters.Appearances", t => t.Appearance_Id)
            .ForeignKey("Characters.Metadata", t => t.MetadataId, cascadeDelete: true)
            .ForeignKey("Characters.Portraits", t => t.Portrait_Id)
            .Index(t => t.MetadataId)
            .Index(t => t.Appearance_Id)
            .Index(t => t.Portrait_Id);

        CreateTable(
            "Characters.Appearances",
            c => new
                {
                    Id = c.Guid(nullable: false),
                    Gender = c.Int(nullable: false),
                    Height = c.Int(nullable: false),
                    Weight = c.Int(nullable: false),
                    SkinColour = c.String(),
                    EyeColour = c.String(),
                    SpecialFeatures = c.String(),
                    HairColour = c.String(),
                    LipColour = c.String(),
                })
            .PrimaryKey(t => t.Id);

        CreateTable(
            "Characters.Metadata",
            c => new
                {
                    Id = c.Guid(nullable: false),
                    Tags = c.String(),
                    VoiceActor = c.String(),
                    Occurrences = c.String(),
                })
            .PrimaryKey(t => t.Id);

        CreateTable(
            "Characters.Portraits",
            c => new
                {
                    Id = c.Guid(nullable: false),
                    Data = c.Binary(),
                })
            .PrimaryKey(t => t.Id);

    }

    public override void Down()
    {
        DropForeignKey("Characters.Character", "Portrait_Id", "Characters.Portraits");
        DropForeignKey("Characters.Character", "MetadataId", "Characters.Metadata");
        DropForeignKey("Characters.Character", "Appearance_Id", "Characters.Appearances");
        DropIndex("Characters.Character", new[] { "Portrait_Id" });
        DropIndex("Characters.Character", new[] { "Appearance_Id" });
        DropIndex("Characters.Character", new[] { "MetadataId" });
        DropTable("Characters.Portraits");
        DropTable("Characters.Metadata");
        DropTable("Characters.Appearances");
        DropTable("Characters.Character");
    }
}

public partial class v0_1_1 : DbMigration
{
    public override void Up()
    {
    }

    public override void Down()
    {
    }
}

The funny thing is: Even though the second migration is empty the update-database command fails. The first migration runs just fine, but then I get an error when starting the program. As additional information here is the constructor of my repository and the configuration file for it.

internal CharacterRepository(IConverter<CharacterItem, Character> characterReadConverter, IConverter<Character, CharacterItem> characterWriteConverter)
    : base("name=RpgTools")
{
    Database.SetInitializer(new MigrateDatabaseToLatestVersion<CharacterRepository, Configuration>(true));
    this.Characters = this.Set<CharacterItem>();

    this.readConverter = new DataConverter<CharacterItem, Character>(characterReadConverter);
    this.bulkReadConverter = new DictionaryRangeConverter<CharacterItem, Guid, Character>(characterReadConverter, c => c.Id);
    this.writeConverter = new DataConverter<Character, CharacterItem>(characterWriteConverter);
}

internal sealed class Configuration : DbMigrationsConfiguration<CharacterRepository>
{
    public Configuration()
    {
        this.AutomaticMigrationsEnabled = false;
    }

    protected override void Seed(CharacterRepository context)
    {
        Guid[] ids =
        {
            new Guid("13cbbdc8-d2e6-4a9a-9525-fa9043a53082"),
            new Guid("3a34fd9b-a6e3-4567-af83-840ddf4417ba"),
            new Guid("b1256f9f-8a35-416a-8f22-6be91ffb4041"),
            new Guid("2e24283d-1ba0-4cc7-b49c-975937e8512c"),
            new Guid("2f66d513-1839-4a26-be7e-39243d6807cf")
        };

        CharacterItem char1 = new CharacterItem
        {
            Age = 22,
            Appearance = new AppearanceItem
            {
                EyeColour = "Green",
                Gender = Genders.Female,
                HairColour = "Red",
                Height = 188,
                Id = ids[1],
                LipColour = "red",
                SkinColour = "fair",
                Weight = 76
            },
            Id = ids[0],
            Metadata = new CharacterMetadataItem
            {
                Id = ids[2],
                Occurrences = string.Empty,
                Tags = "Female; Protagonist"
            },
            Motto = null,
            Name = "Sarah Fenix",
            Nickname = string.Empty,
            Portrait = null,
            Description = "Ravia Hagen's spouse",
            Title = string.Empty
        };

        var char2 = new CharacterItem
        {
            Age = 22,
            Appearance = new AppearanceItem
            {
                EyeColour = "Green",
                Gender = Genders.Female,
                HairColour = "Red",
                Height = 188,
                Id = ids[4],
                LipColour = "red",
                SkinColour = "fair",
                Weight = 76
            },
            Id = ids[3],
            Metadata = new CharacterMetadataItem
            {
                Id = ids[5],
                Occurrences = string.Empty,
                Tags = "Female; Protagonist",
                VoiceActor = string.Empty
            },
            Motto = null,
            Name = "Ravia Hagen",
            Nickname = string.Empty,
            Portrait = null,
            Description = "Sarah Fenix's spouse",
            Title = string.Empty
        };

        context.Characters.AddOrUpdate(c => c.Id, char1, char2);
    }
}
like image 378
Ruhrpottpatriot Avatar asked Jul 11 '15 15:07

Ruhrpottpatriot


2 Answers

The problem isn't the update itself but the fact that the record you are trying to update would break a foreign key constraint.

The UPDATE statement conflicted with the FOREIGN KEY constraint "FK_Characters.Characters_Characters.Appearances_AppearanceId". The conflict occurred in database "RpgTools", table "Characters.Appearances", column 'Id'.

We don't have your DB schema so you will have to search your database to find out what is the FK_Characters.Characters_Characters.Appearances_AppearanceId about an then make sure the record you are trying to update is "legit" with the FK constraint.

like image 149
The_Black_Smurf Avatar answered Oct 18 '22 16:10

The_Black_Smurf


Try [Table("Character", Schema = "Characters")] or just [Table("Characters.Character")] should work, too. Otherwise, EF is trying to use [dbo].[Character].

If the schema difference has been recently introduced, it's likely the root of the problem.

Edit, based on question update:

Not sure how you're getting past the compiler throwing an ArrayOutOfBoundsException – sometimes EF implicitly null coalesces? – but considering your InnerException has to do with Metadata.Id, I consider it suspect that you're using a value off the end of your array to initialize this property (array of 5 means indices 0 - 4, so your ids[5] is out-of-bounds).

Chances are, EF is doing something "magical" for you here rather than throwing ... however, something about that is apparently causing the subsequent FK violation.

You probably had these in a slightly different order when you originally posted, because it had been Appearances.Id that was at fault.

like image 1
John Castleman Avatar answered Oct 18 '22 16:10

John Castleman