Дубликаты в базе данных - PullRequest
2 голосов
/ 28 марта 2019

Я использую 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();
}

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

Ответы [ 2 ]

1 голос
/ 28 марта 2019

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 голос
/ 28 марта 2019

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

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 doesn't exist..
    if(genre == null)
    {
        //Create it 
        genre = new Genre();
        //And set the name
        genre.Name = item;            
    }
    //but, if it already exist, you dont create a new one, just use the existing one
    genrelist.Add(genre);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...