IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

ASP.NET Discussion :

Accès concurrentiel sur une base SQL Server 2005


Sujet :

ASP.NET

  1. #1
    Membre régulier Avatar de Nixar
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    302
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 302
    Points : 85
    Points
    85
    Par défaut Accès concurrentiel sur une base SQL Server 2005
    BOnjour,
    Tout d'abord ma config : XP SP3, SQL Management Studio 2005, Visual Studio 2005

    J'ai un souci qui me rend un peu ... Alor qu'à priori je n'ai qu'une seule connexion ouverte, j'ai une erreur
    "Violation de l'accès concurrentiel : DeleteCommand a affecté 0 des enregistrements 1 attendus."
    . Voici la partie métier, pardon si c'est un peu long je pense que c'est nécessaire (le code est après:

    Pour mon site, j'ai mis en place une newsletter. Cette newsletter porte sur différents thèmes, aussi les users qui s'y inscrivent doivent choisir le ou les thèmes qui les intéressent (par le biais d'une CheckBoxList, bindée sur la table qui contient les thèmes).

    Pour corser un peu le tout, j'ai un espace membres mis en place avec l'appartenance asp.net (tout fonctionne à ce niveau). Les users qui s'inscrivent à la newsletter peuvent être membres, ou pas. Lorsqu'ils sont membres, le système facilité les choses en récupérant les infos de ces users et en préremplissant les contrôles (leur mail, leurs choix pour les thèmes de la newsletter s'ils se sont inscrits déjà et qu'ils veulent les modifier).

    La table qui contient les utilisateurs inscrits à la newsletter contient un enregistrement par thème : si un user choisit les thèmes 1 & 2, il y aura 2 enregistrements dans la table, un par thème. Donc j'ai choisi, lors d'une modification, d'effacer les choix précédents qui ont été fait. Voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
     /// <summary>
        /// Se produit lorsque l'on valide ses choix de newsletter
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Button_Click(object sender, EventArgs e)
        {
            SqlConnection Connexion = Commun.ConnexionBase();
            if (User.Identity.IsAuthenticated)
            {
                SqlDataAdapter SqlDataAdapter1;
                SqlDataAdapter1 = new SqlDataAdapter("SELECT * FROM " + Commun.AccesseurTableNewsletter, Connexion);
                DataSet DataSet1 = new DataSet("DataSet");
                SqlDataAdapter1.Fill(DataSet1, Commun.AccesseurTableNewsletter);
                SqlDataAdapter1.SelectCommand.Dispose();
                bool IsDeleting = false;
     
     
                // On efface toutes les données concernant ce user (avec son ancien mail) pour réécrire son nouveau choix après
                for (int i = 0; i < DataSet1.Tables[Commun.AccesseurTableNewsletter].Rows.Count; i++)
                {
                    if (DataSet1.Tables[Commun.AccesseurTableNewsletter].Rows[i][Commun.AccesseurChampEmailNewsletterBase].ToString() == Membership.GetUser().Email)
                    {
                          DataSet1.Tables[Commun.AccesseurTableNewsletter].Rows[i].Delete();
                        IsDeleting = true;
                    }
                }
     
                if (IsDeleting)
                {
                    // Remplissage de la commande DeleteCommand
                    SqlDataAdapter1.DeleteCommand = new SqlCommand(
                       "DELETE FROM " +
                       Commun.AccesseurTableNewsletter +
                       " WHERE " + Commun.AccesseurChampEmailNewsletterBase + "=@" + Commun.AccesseurChampEmailNewsletterBase, Connexion);
     
     
                    SqlDataAdapter1.DeleteCommand.Parameters.Add("@" + Commun.AccesseurChampEmailNewsletterBase, SqlDbType.VarChar, 50, Commun.AccesseurChampEmailNewsletterBase);
                    SqlDataAdapter1.DeleteCommand.Parameters["@" + Commun.AccesseurChampEmailNewsletterBase].Value = TextBoxEmail.Text;
                    try
                    {
                        SqlDataAdapter1.Update(DataSet1, Commun.AccesseurTableNewsletter);
                    }
                    catch (Exception exc)
                    {
     
                    }
                }
     
                //Si le user choisi de répercuter la modif de son mail, alors on modifie aussi
                if ((TextBoxEmail.Text != Membership.GetUser().Email) && (Convert.ToBoolean(RadioButtonListChoixMail.SelectedValue)))
                {
                    Membership.GetUser().Email = TextBoxEmail.Text; 
                }
                foreach (ListItem chkbox in CheckBoxListTypes.Items)
                {
                    // Si la checkbox est 
                    if (chkbox.Selected)
                    {
                        // Remplissage de la commande InsertCommand
                        if(SqlDataAdapter1.InsertCommand == null)
                        {
                            SqlDataAdapter1.InsertCommand = new SqlCommand("INSERT INTO " + Commun.AccesseurTableNewsletter + " (" + Commun.AccesseurChampUserIdBase + "," + Commun.AccesseurChampEmailNewsletterBase + "," + Commun.AccesseurChampTopicsChosenNewsletterBase + ") Values(@" + Commun.AccesseurChampUserIdBase + ",@" + Commun.AccesseurChampEmailNewsletterBase + ",@" + Commun.AccesseurChampTopicsChosenNewsletterBase + ")", Connexion);
     
                            SqlDataAdapter1.InsertCommand.Parameters.Add("@" + Commun.AccesseurChampUserIdBase, SqlDbType.UniqueIdentifier, 50, Commun.AccesseurChampUserIdBase);
                            SqlDataAdapter1.InsertCommand.Parameters.Add("@" + Commun.AccesseurChampEmailNewsletterBase, SqlDbType.VarChar, 50, Commun.AccesseurChampEmailNewsletterBase);
                            SqlDataAdapter1.InsertCommand.Parameters.Add("@" + Commun.AccesseurChampTopicsChosenNewsletterBase, SqlDbType.VarChar, 1000, Commun.AccesseurChampTopicsChosenNewsletterBase);
                        }
                        DataRow oDataRow;
                        oDataRow = DataSet1.Tables[Commun.AccesseurTableNewsletter].NewRow();
     
                        oDataRow[Commun.AccesseurChampUserIdBase] = Membership.GetUser().ProviderUserKey;
                        oDataRow[Commun.AccesseurChampEmailNewsletterBase] = TextBoxEmail.Text;
                        oDataRow[Commun.AccesseurChampTopicsChosenNewsletterBase] = Convert.ToInt32(chkbox.Value);
     
     
                        DataSet1.Tables[Commun.AccesseurTableNewsletter].Rows.Add(oDataRow);
                        if(!(SqlDataAdapter1.DeleteCommand == null))
                        {
                            SqlDataAdapter1.DeleteCommand.Dispose();
                        }
     
                    }
                }
                try
                {
                    SqlDataAdapter1.Update(DataSet1, Commun.AccesseurTableNewsletter);
                }
                catch (Exception exc)
                {
     
                }
     
            }
    Ca pante quand je fais ca :
    1) je me connecte en tant que membres
    2) je vais m'inscrire à la newsletter alors que je n'étais pas inscrit avant
    3) Ca marche, les infos sont écrites en base
    4) Dans la même session je reviens modifier mes infos de newsletter.. Les données précédemment inscrites sont correctement bindées.
    5) je modifie mes choix.
    6) Je valide et là, j'ai l'exception au niveau de l'update du InsertCommand (le DeleteCommand semble bien se passer.

    OUF ! Désolé pour la longueur, mais je voulais que le max de choses y soient car je ne comprends vraiment pas cette erreur.

    Merci beaucoup de vos réponses et de votre patience !!!

    Nixar

  2. #2
    Membre actif
    Inscrit en
    Janvier 2004
    Messages
    208
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 208
    Points : 227
    Points
    227
    Par défaut
    salut

    normal ton DataAdapter en delete est dans ton appel insert.

    Pour les operations de dataset avec un dataAdapter il faut generalement copié ton dataset et le fusioné a chaque operation.

    la preuve en est, que justement si tu copie et tu fusionne plus besoin de faire une suppression pour refaire un insert. tu jouera simplement avec un updatecommand.

    repense ton DataAdapter pour traité ton DataSet

  3. #3
    Membre averti Avatar de flogreg
    Profil pro
    Développeur informatique
    Inscrit en
    Mars 2004
    Messages
    432
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2004
    Messages : 432
    Points : 392
    Points
    392
    Par défaut
    salut,
    Tu es sur de bien fermer ta connexion à la base de données ?
    Sinon si tu veux voir les connexions ouvertes sur ton server, dans sql server management studio, tu vas dans management puis dans activity monitor.

    edit : en fait, mon message n'a servi qu'à montrer que j'étais à coté de la plaque
    Pas de messages privés sur des questions techniques ! Je suis trop nul pour vous aider

  4. #4
    Membre régulier Avatar de Nixar
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    302
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 302
    Points : 85
    Points
    85
    Par défaut
    @nashouille : merci de ta reponse. Sauf qu'en fait je me rend compte que j'ai pas compris du tout comment ca marchait un DataAdapter... Pour moi il te sert a charger un Dataset. Ensuite tu peux faire toutes les operations que tu veux sur ce Dataset et renvoyer le tout en base sous reserve d'avoir rempli les SqlCommand necessaires dans le DataAdapter.

    normal ton DataAdapter en delete est dans ton appel insert.

    Pour les operations de dataset avec un dataAdapter il faut generalement copié ton dataset et le fusioné a chaque operation.

    la preuve en est, que justement si tu copie et tu fusionne plus besoin de faire une suppression pour refaire un insert. tu jouera simplement avec un updatecommand.
    Est ce que tu veux bien developper un peu, car je ne vois pas du tout comment faire ce que tu dis

    merci beaucoup !

    @flogreg : c'etait pas ca que je voulais mais merci quans meme de l'info je connaissais pas le truc. Merci !

  5. #5
    Membre actif
    Inscrit en
    Janvier 2004
    Messages
    208
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 208
    Points : 227
    Points
    227
    Par défaut
    je t'invite a faire un tour ici

    http://msdn.microsoft.com/fr-fr/libr...1y(VS.80).aspx

    il y a aussi plus dans le menu le necessaire pour traité ton DataSet

    Bon code

  6. #6
    Membre actif

    Inscrit en
    Novembre 2003
    Messages
    168
    Détails du profil
    Informations forums :
    Inscription : Novembre 2003
    Messages : 168
    Points : 232
    Points
    232
    Par défaut
    Salut,

    En général cette erreur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Violation de l'accès concurrentiel : DeleteCommand a affecté 0 des enregistrements 1 attendus."
    se produit lorsque tu supprime une ligne (DataRow) de ton DataSet puis tu exécutes la suppression réelle (dataadapter.update) mais ccette opération ne trouve pas dans la DB les lignes qui ont été supprimées du DataSet, par ne les trouve pas je veux dire la clause where de ta requete delete ne correspond à aucune ligne !

    Je n'ai pas eu le temps de bien lire ton code et donc je me demande ce t'es en train de supprimer et dans quellles conditions !

    Je viens de remarquer ceci aussi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SqlDataAdapter1.DeleteCommand.Parameters["@" + Commun.AccesseurChampEmailNewsletterBase].Value = TextBoxEmail.Text;
    En général quand on utilise un DataAdapter on ne fournit pas la valeur du paramètre mais le champ à l'origine du paramètre ainsi que la version

    Je te conseille de faire un break et d'aller lire un bon tuto sur le mode déconnecté, c'est très facile tu va voir.

  7. #7
    Membre régulier Avatar de Nixar
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    302
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 302
    Points : 85
    Points
    85
    Par défaut
    Bonjour et merci de ta réponse très constructive,
    J'ai fait un test concernant ce que faisait ma requête, à chaque fois que je l'ai fait ca a fonctionné correctement (sous SQL Management Studio). Je ne suis pas à l'abri d'une m**** donc je vais voir ca de plus près.

    Concernant le paramètre, je vois ce que tu veux dire, mais dans ce cas comment lui transmets-tu la valeur du param? Tu parles d'un bon tuto sur le mode déconnecté, je n'ai pas trouvé jusqu'à maintenant e tuto qui me permettait de faire tourner ce que je cherche à faire, si tu en as un bien je suis preneur !!

    Merci beaucoup.

    Cordialement,

    Nixar

Discussions similaires

  1. Réponses: 4
    Dernier message: 28/03/2012, 10h50
  2. Réponses: 1
    Dernier message: 23/09/2010, 09h03
  3. Réponses: 0
    Dernier message: 14/09/2010, 16h51
  4. Réponses: 9
    Dernier message: 19/06/2008, 12h19
  5. Copie de table sur une base SQL Server 2005
    Par stephyugh dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 09/04/2008, 13h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo