コードファーストアプローチでEntityFramework5を使用しています。
互いに多対多の関係にある2つのクラスがMovieありPersonます。Aは経由Movieでに関連付けられています。それぞれに複数の文字を含めることができます。PersonCharacterMovie
public class Movie {
public int Id { get; set; }
public string Title { get; set; }
public int? Year { get; set; }
public virtual ICollection<Character> Characters { get; set; }
public Movie() {
Characters = new HashSet<Character>();
}
}
public class Character {
public string Name { get; set; }
public virtual Movie Movie { get; set; }
public virtual Person Person { get; set; }
}
public class Person {
public int Id { get;set; }
public string Name { get; set; }
public virtual ICollection<Character> Characters { get; set; }
public Person() {
Characters = new HashSet<Character>();
}
}
場合によっては、複数のを再生するMovieものを使用できます。この状況でアンダーを追加しようとすると、問題が発生します...PersonCharacterMovie
Movie1に2人のキャラクターがいて、両方ともPerson1が演じているとしましょう。変更を保存すると、EFはCharacter1から開始し、Person1がデータベースに存在しないことを確認し、それをに挿入しPersonますdbo.Person。次に、Character2に移動しますが、Person1がすでに存在し、主キー違反をスローすることを確認します。
私MovieRepositoryにはAdd(Movie entity)方法があります。CharacterそれぞれをループしてMovie、関連するものがデータベースに存在するかどうかを確認しPersonます。もしそうなら、私はPersonプロパティを既存のに設定しますPerson。これは通常の場合に機能しますが、Personがまったく存在しない場合は、PK違反を回避する方法がわかりません。これが私の問題です:)
public class MovieRepository : Repository<Movie> {
public MovieRepository(MovieContext context) : base(context) {}
public override void Add(Movie entity) {
foreach (var character in entity.Characters) {
var person = Context.People.FirstOrDefault(p => p.Id == character.Person.Id);
if (person != null)
character.Person = person;
}
Context.Movies.Add(entity);
}
}
もう少し情報を追加するだけです。リポジトリとコンテキストを保持するために、作業ユニットパターンでリポジトリパターンを使用しています。したがって、UnitOfWorkクラスはを担当しSaveChanges()ます。
でこれを実行しようとすると、MovieRepository.Add()このタスクを実行するための最良/適切な方法ではない場合があります。私はありとあらゆる提案を楽しみにしています。
さらに明確にするために、Rotten Tomatoes APIからデータを取得していますが、jsonは次のようになっています...
{data : [{
Id: 12345,
Title: 'Movie1',
Year: 2010,
Character: [{
Name: 'Character1',
Person: { Id: 1, Name: 'Person1' }
},{
Name: 'Character2',
Person: { Id: 2, Name: 'Person2' }
}]
}]}