3

EF Code Firstで既存のデータベースを使用し、modelBuilderを使用して構成しています。SESSIONがSUBJECTを持つことができる2つのテーブルがあり、クラスはそのようなものです。

public class SessionItem {
   [Key]
   public int SessionId { get;set; }
   // Other Values
   public int Subject_ID { get;set; }

   public virtual Subject Subject { get;set; }
}

public class SubjectItem {
   [Key]
   public int Subject_ID { get;set; }
   // Other Values

   public virtual SessionItem Session { get;set; }
}

そして、modelBuilderコードは次のとおりです。

modelBuilder.Entity<SessionItem>().ToTable("tblTblSessions");
modelBuilder.Entity<Subject>().ToTable("tblTblSubjects");
modelBuilder.Entity<SessionItem>()
   .HasOptional<Subject>(u => u.Subject)                     
   .WithOptionalDependent(c => c.Session).Map(p => p.MapKey("Subject_ID"));

これは、SessionItemクラスからSubject_IDを削除するまで最初は失敗しましたが、次のエラーが発生しました。関係の多重度制約違反が発生しました:EntityReferenceは複数の関連オブジェクトを持つことができますが、クエリは複数の関連オブジェクトを返しました。これは回復不可能なエラーです。

私がどこで間違っているのか考えていますか?

4

3 に答える 3

2

EFは一意キー制約( Sessionテーブルの列にあるように見える)を認識していないため、残念ながら1対1の外部キーの関連付けはEntityFrameworkではサポートされていません。Subject_ID

関係を1対多としてマッピングすることにより、これを回避する必要があります。SessionItemエンティティおよびエンティティの@flemの回答のマッピングに従って、完全にSubjectItem削除するか、次のようpublic virtual SessionItem Session { get;set; }に置き換えます。

public virtual ICollection<SessionItem> Sessions { get; set; }

この関係では、Fluent APIを使用したマッピングはもう必要ありません。必要に応じて、次のようにする必要があります。

modelBuilder.Entity<SessionItem>()
    .HasOptional(se => se.Subject)                     
    .WithMany() // or WithMany(su => su.Sessions)
    .HasForeignKey(se => se.Subject_ID);

Subject_IDそのコレクションにアイテムを追加するときは、一意のキーの制約のためにデータベースに同じ行を複数持つことはできないため、ビジネスロジックで複数のアイテムを追加しないようにする必要があり ます。セッションを含むデータベースからサブジェクトをロードすると、セッションコレクションは空であるか、単一の要素を持ちますが、それ以上はありません。

于 2012-07-23T14:39:04.977 に答える
2

これを試して:

public class SessionItem 
{
   [Key]
   public int SessionId { get;set; }
   // Other Values
   [ForeignKey("Subject")]
   public int? Subject_ID { get;set; }

   [ForeignKey("Subject_ID")]    
   public virtual SubjectItem Subject { get;set; }
}

Subject_ID外部キーをnull許容にする必要があります。

于 2012-07-23T13:50:38.353 に答える
1
[Table("tblTblSessions")]
public class SessionItem {
    [Key]
    public int SessionId { get; set; }

    public virtual SubjectItem Subject { get; set; }
}

[Table("tblTblSubjects")]
public class SubjectItem {
    [Key, ForeignKey("Session")]
    public int Subject_ID { get; set; }

    public virtual SessionItem Session { get; set; }
}

SubjectItemとSessionItemの間の1対1の関係、およびすべてのmodelBuilderコードを取り除くことができます-実行していたすべてのテーブルの命名と1対1のマッピングは、上記の属性とプロパティで処理されます。

編集:タイプミスを修正し、1対1の依存側をマークしました。

于 2013-03-30T08:36:45.677 に答える