Re: EF6 - Error inserting 2 related objects in a single SaveChanges
Posted by: Fernando Gonzalez Sanchez
Date: March 06, 2014 12:05PM

Hi,

I cannot reproduce this, and you don't show the full example,
Here's is my full test case that works:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using MySql.Data.Entity;
using System.Data.Entity.Migrations;
using System.Data.Entity.Migrations.History;
using System.Data.Common;


namespace EF6UnitOfWorkPattern
{
public class Program
{
static void Main(string[] args)
{
using (QuoteDBContext ctx = new QuoteDBContext())
{
ctx.Database.Delete();
ctx.Database.CreateIfNotExists();

var client = new Client();
ctx.Clients.Add(client);
var quote = new Quote();
quote.Client = client;
ctx.Quotes.Add(quote);
ctx.SaveChanges();
}
}
}

[DbConfigurationType(typeof(MySqlEFConfiguration))]
public class QuoteDBContext : DbContext
{
public DbSet<Quote> Quotes { get; set; }
public DbSet<Client> Clients { get; set; }

public QuoteDBContext()
{
Database.SetInitializer<QuoteDBContext>(new QuoteDBInitialize());
Database.SetInitializer<QuoteDBContext>(new MigrateDatabaseToLatestVersion<QuoteDBContext, Configuration<QuoteDBContext>>());
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Configurations.AddFromAssembly(System.Reflection.Assembly.GetExecutingAssembly());
}
}

public class QuoteDBInitialize : DropCreateDatabaseReallyAlways<QuoteDBContext>
{
protected override void Seed(QuoteDBContext ctx)
{
base.Seed(ctx);
}
}

/// <summary>
/// This initializer really drops the database, not just once per AppDomain (like the DropCreateDatabaseAlways).
/// </summary>
/// <typeparam name="TContext"></typeparam>
public class DropCreateDatabaseReallyAlways<TContext> : IDatabaseInitializer<TContext> where TContext : DbContext
{
public void InitializeDatabase(TContext context)
{
context.Database.Delete();
context.Database.CreateIfNotExists();
this.Seed(context);
context.SaveChanges();
}

protected virtual void Seed(TContext context)
{
}
}

public class MyHistoryContext : MySqlHistoryContext
{
public MyHistoryContext(DbConnection existingConnection, string defaultSchema)
: base(existingConnection, defaultSchema)
{
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);

modelBuilder.Entity<HistoryRow>().ToTable("__MySqlMigrations");
modelBuilder.Entity<HistoryRow>().Property(h => h.MigrationId).HasColumnName("_MigrationId");
modelBuilder.Entity<HistoryRow>().Property(h => h.ContextKey).HasColumnName("_ContextKey");
modelBuilder.Entity<HistoryRow>().Property(h => h.Model).HasColumnName("_Model");
modelBuilder.Entity<HistoryRow>().Property(h => h.ProductVersion).HasColumnName("_ProductVersion");
}
}

public class Configuration<TContext> : DbMigrationsConfiguration<TContext> where TContext : DbContext
{
public Configuration()
{
CodeGenerator = new MySqlMigrationCodeGenerator();
AutomaticMigrationsEnabled = true;
SetSqlGenerator("MySql.Data.MySqlClient", new MySql.Data.Entity.MySqlMigrationSqlGenerator());
SetHistoryContextFactory("MySql.Data.MySqlClient", (existingConnection, defaultSchema) => new MyHistoryContext(existingConnection, defaultSchema));
}
}

public class Client
{
[Key]
public long Id { get; set; }
}

public class Quote
{
[Column("Id")]
[Key]
public long Id { get; set; }

[Column("Client")]
[ForeignKey("Client")]
public long ClientId { get; set; }

public virtual Client Client { get; set; }
}
}

*** My opinions do not necessarily reflect the opinions of my employeer ***
Fernando Gonzalez Sanchez
Sr. Software Engineer
MySql Connector/NET Team
Oracle Corporation

Options: ReplyQuote




Sorry, you can't reply to this topic. It has been closed.

Content reproduced on this site is the property of the respective copyright holders. It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.