Дубликаты в базе данных

2

Я использую vs2017 с entityframework 6.1.0 и winforms. Что касается сущности, я использую код в первую очередь. Мне нужно сделать приложение для фильма, я сделал для них все классы Movie, Genre и Cast (актеры). Все Genres предварительно вставляются в базу данных. При использовании update-database создается все, включая объединение таблиц moviegenre и cast cast, а также чужих клавиш. Когда я вставляю объект фильма. он связывает идентификатор из жанра актерского состава и фильмов, но также переустанавливает каждый жанр, что означает, что у меня есть дубликаты. Я хочу только ссылки, конечно. Пока это мой код.

класс фильма:

public class Movie
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]       
    public int MovieId { get; set; }

    [Required]
    [StringLength(255)]
    public string Name { get; set; }

    //[ForeignKey("GenreId")]
    public virtual List<Genre> Genre { get; set; }

    //[ForeignKey("CastId")]
    public virtual List<Cast> cast { get; set; }

    [Required]    
    public int GenreId { get; set; }

    [Required]      
    public int CastId { get; set; }

    [Display(Name = "Release Date")]
    public DateTime ReleaseDate { get; set; }

    public Movie()
    {
        Genre = new List<Genre>();
        cast = new List<Cast>();
    }
}

Жанр и состав актеров (одинаковые для обоих классов)

public class Genre
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]       
    public int GenreId { get; set; }

    [Required]
    [StringLength(255)]
    public string Name { get; set; }

    public List<Movie> Movies { get; set; }
}

и, конечно, мой код (этот фрагмент кода от события нажатия кнопки, чтобы добавить фильм в БД.):

private void btnAddMovie_Click(object sender, EventArgs e)
{
    List<Genre> genrelist = new List<Genre>();
    List<Cast> castlist = new List<Cast>();

    var movie = new Movie();                       


    movie.Name = txtTitle.Text;
    movie.ReleaseDate = released;

    //creating lists
    foreach (string item in lbgenre2.Items)
    {
        var genre = new Genre();
        genre.Name = item;
        genrelist.Add(genre);
    }

    foreach (string item in lbCast2.Items)
    {
        var cast = new Cast();
        cast.Name = item;
        castlist.Add(cast);

    }

    movie.Genre = genrelist;
    movie.cast = castlist;


    _context.movies.Add(movie);

    Save();                        
}

private async void Save()
{
    await _context.SaveChangesAsync();
}

Что я делаю не так, что он связывает и вставляет его?

  • 0
    вы снова создаете жанры, хотите добавить жанры в фильме добавить? или все жанры уже созданы?
  • 0
    При вставке фильмов не создавайте новые объекты жанра, а вместо этого запросите список жанров из таблицы жанров и назначьте этот список в Movie.Genre.
Показать ещё 1 комментарий
Теги:
winforms
entity-framework-6

2 ответа

1

Ваша проблема в том, что вы снова создаете жанры и снова и снова каждый раз, когда добавляете новый фильм, и у вас есть Identity Key, поэтому исключение не выдается.

foreach (string item in lbgenre2.Items)
{
    //Here is your problem, you are creating a new Genere instead of using the already created
    var genre = new Genre();
    genre.Name = item;        
    genrelist.Add(genre);
}

Поэтому вместо создания используйте ef, чтобы получить существующие

foreach (string item in lbgenre2.Items)
{
    //try to get the genere from database
    var genre = _context.generes.FirstOrDefault(x => x.Name == item);    
    //if it dont exist..
    if(genre == null)
    {
        //Create it 
        genre = new Genre();
        //And set the name
        genre.Name = item;            
    }
    //but, if it already exist, you didn't create a new one, just use the existing one
    genrelist.Add(genre);
}
1

Entity Framework не может выяснить, если Genre или Cast уже существует, даже если вы сделаете экземпляр одного из них, с одинаковыми свойствами в той, которая существует в базе данных. Вместо этого вам нужно получить существующие жанры и привести их из базы данных и применить их. И только создать новый экземпляр, если это совершенно новый жанр или актерский состав, которого нет в базе данных:

Псевдо-код:

SaveMovie(Movie movie)
{
    var existingGenres = GetGenresFromDatabase();
    var movieGenres = GetGenresFromListBox();

    foreach (var genre in movieGenres)
    {
        if (genre in existingGenres)
        {
            existingGenre = existingGenres.Where(genreId = genre.Id);
            movie.Genres.Add(existingGenre)
        }
        else 
        {
            movies.Add(genre)
        }
    }

    dbcontext.Add(movie);
    dbcontext.SaveChanges();
}
  • 1
    Разве Где не вернуть IQueryable, который не подходит для Add, который предназначен для добавления одной сущности?
  • 0
    @mami, наверное, поэтому я и назвал это «псевдокодом» :-). В идеале вы, вероятно, искали бы что-то вроде FirstOrDefaultAsync или даже создавали отдельный метод для получения существующих жанров.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню