数据库中的重复项

Duplicates in database

我将 vs2017 与 entityframework 6.1.0 和 winforms 一起使用。至于 entityframework 我使用代码优先。我需要制作一个电影应用程序,我已经为他们 MovieGenreCast(演员)制作了所有 classes。 所有 Genres 都预先插入到数据库中。使用 update-database 时,会创建所有内容,包括连接表 moviegenre 和 movie cast 以及外键。当我插入电影对象时。它链接了来自类型演员和电影的 ID,但它也重新插入了每个类型,这意味着我有重复项。我当然只想要链接。到目前为止,这是我的代码。

电影class:

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>();
    }
}

类型和演员表(classes 相同)

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();
}

链接并重新插入它是我做错了什么?

你的问题是因为你要再次创建 Generes,并且每次添加新电影时都要重新创建,并且你有一个身份密钥,所以不会抛出异常。

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);
}

Entity Framework 无法确定 GenreCast 是否已经存在,即使您创建了其中之一的实例,其属性与数据库中存在的实例具有相同的属性.相反,您需要从数据库中获取现有类型和演员表并应用它们。并且只创建一个新的实例,如果它是一个全新的类型或演员表,它不在数据库中:

伪代码:

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();
}