0

これは、Entity Framework 4 (4.3.1) と 5 の両方に当てはまります。

User クラスがあります (Entity Framework MembershipProvider と一緒に使用します)。簡単にするために、一部のプロパティを削除しました。実際の User は MVCBootstrap プロジェクトのものであるため、他のクラスと同じアセンブリの一部ではありません。

public class User {
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }
    [Required]
    [StringLength(256)]
    public String Username { get; set; }
}

そして、私はこのクラスを持っています:

public class NewsItem {
    public Int32 Id { get; set; }
    [Required]
    [StringLength(100)]
    public String Headline { get; set; }
    [Required]
    public virtual User Author { get; set; }
    [Required]
    public virtual User LastEditor { get; set; }
}

次に、データベース コンテキストを作成します (ユーザーの DbSet は MembershipDbContext にあります)。

public class MyContext : MVCBootstrap.EntityFramework.MembershipDbContext {
    public MyContext(String connectString) : base(connectString) { }
    public DbSet<NewsItem> NewsItems { get; set; }
}

このコードを実行すると、データベースの作成時に次の例外が発生します。

テーブル 'WebShop' に FOREIGN KEY 制約 'FK_dbo.WebShop_dbo.User_LastEditor_Id' を導入すると、サイクルまたは複数のカスケード パスが発生する可能性があります。ON DELETE NO ACTION または ON UPDATE NO ACTION を指定するか、他の FOREIGN KEY 制約を変更します。制約を作成できませんでした。以前のエラーを参照してください。

そこで、データベース コンテキストを変更します。

public class MyContext : MVCBootstrap.EntityFramework.MembershipDbContext {
    public MyContext(String connectString) : base(connectString) { }
    public DbSet<NewsItem> NewsItems { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Configurations.Add(new NewsItemConfiguration());
    }
}

そして、この構成:

public class NewsItemConfiguration : EntityTypeConfiguration<NewsItem> {
    public NewsItemConfiguration() {
        HasRequired(n => n.Author).WithOptional();
        HasRequired(n => n.LastEditor).WithOptional();
    }
}

それともこれは間違っていますか?

とにかく、コードを実行すると、データベースが作成され、データベースは問題ないように見えます (外部キー制約などを調べます)。

しかし、その後、コンテキストから 10 個の最新の NewsItem を取得し、それらをビュー モデルにロードし始めます。これの一部は、NewsItem の Author プロパティにアクセスすることです。これを行うコントローラーは、ロードに永遠に時間がかかり、長い間失敗します。デバッグモードで実行すると、このコードで例外が発生します: this.AuthorId = newsItem.Author.Id;、次に取得する例外は次のとおりです:

関係の多重度制約違反が発生しました: EntityReference は複数の関連オブジェクトを持つことはできませんが、クエリは複数の関連オブジェクトを返しました。これは回復不可能なエラーです。

おそらく、私が間違っているのは単純で愚かなことです。複数のサイトで同様のコードを実行していると確信しています..これは何が原因ですか? 私のモデルは間違っていますか、それはデータベースのコンテキストですか、それとも?

4

2 に答える 2

0

この部分

テーブル 'WebShop' に FOREIGN KEY 制約 'FK_dbo.WebShop_dbo.User_LastEditor_Id' を導入すると、サイクルまたは複数のカスケード パスが発生する可能性があります。ON DELETE NO ACTION または ON UPDATE NO ACTION を指定するか、他の FOREIGN KEY 制約を変更します。制約を作成できませんでした。以前のエラーを参照してください。

実際には SQL Server の問題 (および他の多くの RDBMS の問題) です。これは、複数のカスケード パスを解決する複雑な問題であり、SQL Server は試行せずに単にパントすることを決定します。見る

外部キー制約により、サイクルまたは複数のカスケード パスが発生する可能性がありますか?

NewsItem が削除されたときに子の Author および LastEditor オブジェクトを削除するようにモデルを構成しようとしました。SQL Server はそれを行いません。

そういえば……それが欲しいの? データベースから削除するのではなく、NewsItem から Author と LastEditor の関連付けを解除したいようです。

オブジェクト モデルでは、NewsItem と Author の間、および NewsItem と LastEditor の間に 1 対 1 の関係が必要です。これがコードで何を指しているのかわかりません

this.AuthorId = newsItem.Author.Id;

しかし、私には思えますが、割り当てを逆にする必要があります。

newsItem.Author = myAuthorInstance;

または、モデルに外部キー プロパティを含め、以前に作成者インスタンスを保存して ID を持っている場合:

newsItem.AuthorId = myAuthorInstance.Id; 

生成された DB スキーマ (関連部分) を共有すると、問題の診断が容易になります。

于 2012-09-21T06:55:32.577 に答える
0

ユーザーは、いくつかのニュース項目の作成者になることができます。また、ユーザーは複数のニュース項目の編集者になることもできます。
したがって、関係は「1 対多」でなければなりません。

public class NewsItemConfiguration : EntityTypeConfiguration<NewsItem> {
    public NewsItemConfiguration() {
        HasRequired(n => n.Author).WithMany();
        HasRequired(n => n.LastEditor).WithMany();
    }
}
于 2012-09-21T07:09:27.007 に答える