私のアプリケーションは .NET 4.5 を対象としており、EntityFramework 5.0、Sql Server Compact 4.0 を使用しています。
データベースにいくつかのエンティティをシードしようとしていますが、スローし続けます:
「System.Data.SqlServerCe.SqlCeException: 対応する主キー値が存在しないため、外部キー値を挿入できません。[外部キー制約名 = FK_dbo.User_dbo.Account_AccountKey ]」
以下は、私のドメイン エンティティの簡易版です。
public class Account
{
public int AccountKey { get; set; }
public string Name { get; set; }
public ICollection<User> Users { get; set; }
}
internal class AccountMap : EntityTypeConfiguration<Account>
{
public AccountMap()
{
this.HasKey(e => e.AccountKey);
this.Property(e => e.AccountKey).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
this.Property(e => e.Name).IsRequired();
}
}
public class User
{
public int UserKey { get; set; }
public string Name { get; set; }
public Account Account { get; set; }
public int AccountKey { get; set; }
}
internal class UserMap : EntityTypeConfiguration<User>
{
public UserMap()
{
this.HasKey(e => e.UserKey);
this.Property(e => e.UserKey).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
this.Property(e => e.Name).IsRequired();
this.HasRequired(e => e.Account)
.WithMany(e => e.Users)
.HasForeignKey(e => e.AccountKey);
}
}
public class TestContext : DbContext
{
public TestContext()
{
this.Configuration.LazyLoadingEnabled = false;
}
public DbSet<User> Users { get; set; }
public DbSet<Account> Accounts { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); modelBuilder.Conventions.Remove<StoreGeneratedIdentityKeyConvention>();
modelBuilder.LoadConfigurations();
}
}
接続文字列:
<connectionStrings>
<add name="TestContext" connectionString="Data Source=|DataDirectory|\TestDb.sdf;" providerName="System.Data.SqlServerCe.4.0" />
</connectionStrings>
この問題を示すサンプル アプリケーションを次に示します。
class Program
{
static void Main(string[] args)
{
try
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<TestContext>());
using (var context = new TestContext())
context.Database.Initialize(false);
for (int i = 0; i < 2; i++ )
using (var context = new TestContext())
{
var account1 = new Account()
{
Name = "Account1"
};
var user1 = new User()
{
Name = "User1",
Account = account1
};
context.Accounts.AddOrUpdate(
e => e.Name,
account1
);
context.Users.AddOrUpdate(
e => e.Name,
user1
);
context.SaveChanges();
Console.WriteLine("\nChanges saved.");
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("\nPress any key to exit...");
Console.ReadLine();
}
}
Account クラスは、User クラスと 1 対多の関係にあります。私のシード メソッドは、デフォルトのユーザーでデフォルトのアカウントを初期化しようとします。これは AddOrUpdate メソッドの一般的な使用方法だと思われるかもしれませんが、この場合は機能しないようです。ユーザーなしで同じアカウントを 2 回追加すると、問題なく動作します。
誰が私が欠けている点を見ることができますか?
この単純な関係に何か問題がありますか?
AddOrUpdate メソッドは、このような状況で機能するように設計されていますか?
そうでない場合、その種のシードを達成するための正しいアプローチは何でしょうか?