[C# - Code First]多对多插入两次

[C# - CodeFirst]Many to Many inserting two times

首先,对于普通的英语和对 Whosebug 的滥用感到抱歉

我正在开发类似餐厅的应用程序,我必须处理: - 服务员 - 菜 - 订单,其中包含菜肴清单和负责的服务员 - Table 有订单

问题是每当我添加一个新命令时,它都会重新插入盘子,即使它们的 ID 已经存在:(

这是主要代码,其中"plats"表示Dish,"serveurs"表示"waiters","commande"表示"order"。

        public void ouvrirFenetreNouvelleCommande(int x, int y)
    {
        commande_gestion nouvelleCommande = new commande_gestion(plats, serveurs) { tabX = x, tabY = y };

        nouvelleCommande.raiseNewCommandEvent += new EventHandler<Commande>(creerNouvelleCommande);
        nouvelleCommande.tabX = x;
        nouvelleCommande.tabY = y;
        nouvelleCommande.ShowDialog();

    }

    public void ouvrirFenetreEncaisserCommande(int x, int y)
    {
        mettreAJourGrillePrincipale();
    }

    public void creerNouvelleCommande(object sender, Commande e)
    {
        var fenetre = sender as commande_gestion;
        int i = 0;

        foreach(var item in tables)
        {
            if(item.TabX == fenetre.tabX && item.TabY == fenetre.tabY)
            {
                using (var db = new RestaurantContext())
                {
                    db.Commandes.Add(e);

                    foreach(var item2 in e.ListePlats)
                    {
                        MessageBox.Show(String.Format("ID : {0} - Nom : {1}", item2.platId, item2.Nom));
                    }

                    db.SaveChanges();

                    tables[i].commandeId = e.commandeId;
                    tables[i].Etat = (int)Etats.OCCUPE;
                }

                mettreAJourGrillePrincipale();
            }
            i++;
        }
    }

我的代码 window "commande_gestion" :

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Linq;
using System.Collections.ObjectModel;

namespace RestaurantManagerDeluxe
{
/// <summary>
/// Logique d'interaction pour commande_gestion.xaml
/// </summary>
public partial class commande_gestion : Window
{
    public ObservableCollection<Plat> platsChoisis;
    public List<Plat> plats;
    public List<Serveur> serveurs;
    public double prixTotalPlatsChoisis;

    public event EventHandler<Commande> raiseNewCommandEvent;

    public int tabX { get; set; }
    public int tabY { get; set; }

    public commande_gestion(List<Plat> listePlats, List<Serveur> listeServeurs)
    {
        InitializeComponent();

        prixTotalPlatsChoisis = 0;
        platsChoisis = new ObservableCollection<Plat>();

        listBoxNouveauPlats.ItemsSource = platsChoisis;
        updateRecap();

        plats = listePlats;
        serveurs = listeServeurs;

        listBoxPlatsExistant.ItemsSource = plats;
        listBoxResponsable.ItemsSource = serveurs;
    }

    private void ajouterNouveauPlat_Click(object sender, RoutedEventArgs e) // Appui sur le bouton "Ajouter"
    {
        if (listBoxPlatsExistant.SelectedIndex < 0)
            return;

        platsChoisis.Add(listBoxPlatsExistant.SelectedItem as Plat);
        updateRecap();
    }

    private void enleverPlat_Click(object sender, RoutedEventArgs e) // Appui sur le bouton "Enlever"
    {
        if (listBoxNouveauPlats.SelectedIndex < 0)
            return;

        platsChoisis.RemoveAt(listBoxNouveauPlats.SelectedIndex);
        updateRecap();
    }

    public void updateRecap() // Mets à jour le récapitulatif de la quantité de plats et de la somme totale
    {
        prixTotalPlatsChoisis = 0;
        foreach(var item in platsChoisis)
        {
            prixTotalPlatsChoisis += item.Prix;
        }

        labelRecap.Content = String.Format("Vous avez cumulé un total de {0} plats pour la somme totale de {1}€", platsChoisis.Count, prixTotalPlatsChoisis);
    }

    private void boutonFinaliserCommande_Click(object sender, RoutedEventArgs e) // Lors de l'appui sur le bouton "Finaliser la Commande", ou "Terminer"
    {
        Commande nouvelleCommande = new Commande();
        nouvelleCommande.ListePlats = new List<Plat>();

        foreach(var item in platsChoisis) // On récupère chaque plat dans la liste des plats que l'on a choisi
        {
            nouvelleCommande.ListePlats.Add(item);
            MessageBox.Show(String.Format("id: {0}", item.platId));
        }

        nouvelleCommande.Traite = false; // False car on a pas encore encaissé le paiement
        nouvelleCommande.ResponsableId = (listBoxResponsable.SelectedItem as Serveur).serveurId;

        if(nouvelleCommande.ListePlats.Count <= 1)
        {
            MessageBox.Show("Vous n'avez renseigné aucun plat", "Commande Impossible", MessageBoxButton.OK, MessageBoxImage.Error);
        }
        if(nouvelleCommande.ResponsableId == 0)
        {
            MessageBox.Show("Vous devez choisir un Responsable de table", "Commande Impossible", MessageBoxButton.OK, MessageBoxImage.Error);
            return;
        }

        raiseNewCommandEvent(this, nouvelleCommande); // On envoi la nouvelle commande à la fenêtre principale qui lui affectera la table
        this.Close();
    }
}

}

也许你应该添加这个:

 nouvelleCommande.Plat.Attach(item); //Add this

像那样:

 private void boutonFinaliserCommande_Click(object sender, RoutedEventArgs e) // Lors de l'appui sur le bouton "Finaliser la Commande", ou "Terminer"
{
    Commande nouvelleCommande = new Commande();
    nouvelleCommande.ListePlats = new List<Plat>();

    foreach(var item in platsChoisis) // On récupère chaque plat dans la liste des plats que l'on a choisi
    {
        nouvelleCommande.Plat.Attach(item); //Add this
        nouvelleCommande.ListePlats.Add(item);
        MessageBox.Show(String.Format("id: {0}", item.platId));
    }

    nouvelleCommande.Traite = false; // False car on a pas encore encaissé le paiement
    nouvelleCommande.ResponsableId = (listBoxResponsable.SelectedItem as Serveur).serveurId;

    if(nouvelleCommande.ListePlats.Count <= 1)
    {
        MessageBox.Show("Vous n'avez renseigné aucun plat", "Commande Impossible", MessageBoxButton.OK, MessageBoxImage.Error);
    }
    if(nouvelleCommande.ResponsableId == 0)
    {
        MessageBox.Show("Vous devez choisir un Responsable de table", "Commande Impossible", MessageBoxButton.OK, MessageBoxImage.Error);
        return;
    }

    raiseNewCommandEvent(this, nouvelleCommande); // On envoi la nouvelle commande à la fenêtre principale qui lui affectera la table
    this.Close();
}