2013-02-18 6 views

Répondre

0

Il existe des moyens de "verrouiller" les enregistrements à un utilisateur à la fois, mais cela aboutit à une base de données très lente, sans compter que ce n'est tout simplement pas si pratique dans des situations réelles. La meilleure méthode pour éviter les problèmes de simultanéité consiste à capturer les valeurs d'origine lorsque la grille est chargée et une fois qu'une instruction de mise à jour ou une instruction de suppression est exécutée, la base de données rejette la commande si les valeurs d'origine ne correspondent pas. Jetez un oeil sur le code ci-dessous pour ce projet que j'ai fait il y a quelques semaines. Portez une attention particulière aux références des valeurs d'origine.

<asp:SqlDataSource ID="SqlDataSource2" runat="server" 
      ConflictDetection="CompareAllValues" 
      ConnectionString="<%$ ConnectionStrings:TechSupport_DataConnectionString %>" 
      DeleteCommand="DELETE FROM [Technicians] WHERE [TechID] = @original_TechID AND [Name] = @original_Name AND [Email] = @original_Email AND [Phone] = @original_Phone" 
      InsertCommand="INSERT INTO [Technicians] ([Name], [Email], [Phone]) VALUES (@Name, @Email, @Phone)" 
      OldValuesParameterFormatString="original_{0}" 
      SelectCommand="SELECT * FROM [Technicians] WHERE ([TechID] = @TechID)" 
      UpdateCommand="UPDATE [Technicians] SET [Name] = @Name, [Email] = @Email, [Phone] = @Phone WHERE [TechID] = @original_TechID AND [Name] = @original_Name AND [Email] = @original_Email AND [Phone] = @original_Phone"> 
      <SelectParameters> 
       <asp:ControlParameter ControlID="DropDownList1" Name="TechID" 
        PropertyName="SelectedValue" Type="Int32" /> 
      </SelectParameters> 
      <DeleteParameters> 
       <asp:Parameter Name="original_TechID" Type="Int32" /> 
       <asp:Parameter Name="original_Name" Type="String" /> 
       <asp:Parameter Name="original_Email" Type="String" /> 
       <asp:Parameter Name="original_Phone" Type="String" /> 
      </DeleteParameters> 
      <UpdateParameters> 
       <asp:Parameter Name="Name" Type="String" /> 
       <asp:Parameter Name="Email" Type="String" /> 
       <asp:Parameter Name="Phone" Type="String" /> 
       <asp:Parameter Name="original_TechID" Type="Int32" /> 
       <asp:Parameter Name="original_Name" Type="String" /> 
       <asp:Parameter Name="original_Email" Type="String" /> 
       <asp:Parameter Name="original_Phone" Type="String" /> 
      </UpdateParameters> 
      <InsertParameters> 
       <asp:Parameter Name="Name" Type="String" /> 
       <asp:Parameter Name="Email" Type="String" /> 
       <asp:Parameter Name="Phone" Type="String" /> 
      </InsertParameters> 
     </asp:SqlDataSource> 

Après avoir réglé les instructions SQL, alors vous avez juste besoin de code pour gérer les exceptions de base de données à l'aide de gestionnaires d'événements tels que « élément inséré », etc. Voir le code ci-dessous.

protected void DetailsView1_ItemUpdated(object sender, DetailsViewUpdatedEventArgs e) 
    { 
     if (e.Exception != null) 
     { 
      lblError.Text = "A database error has occurred.<br /><br />" + "Message: " + e.Exception.Message; 
      e.ExceptionHandled = true; 
      e.KeepInEditMode = true; 
     } 
     else if (e.AffectedRows == 0) 
      lblError.Text = "Another user may have updated that product." + "<br />Please try again."; 
     else 
      DetailsView1.DataBind(); 
    } 
    protected void DetailsView1_ItemDeleted(object sender, DetailsViewDeletedEventArgs e) 
    { 
     if (e.Exception != null) 
     { 
      lblError.Text = "A database error has occurred.<br /><br />" + "Message: " + e.Exception.Message; 
      e.ExceptionHandled = true; 
     } 
     else if (e.AffectedRows == 0) 
      lblError.Text = "Another user may have updated that product." + "<br />Please try again."; 
     else 
      DetailsView1.DataBind(); 
      DropDownList1.DataBind(); 
    } 
    protected void DetailsView1_ItemInserted(object sender, DetailsViewInsertedEventArgs e) 
    { 
     if (e.Exception != null) 
     { 
      lblError.Text = "A database error has occurred.<br /><br />" + "Message: " + e.Exception.Message; 
      e.ExceptionHandled = true; 
      e.KeepInInsertMode = true; 
     } 
     else 
      DetailsView1.DataBind(); 
     DropDownList1.DataBind(); 

    } 

Espérons que ça aide.

0

Si vous voulez éviter les erreurs de concurrence au niveau de la base de données, vous le feriez avec le code que vous avez utilisé pour mettre à jour l'enregistrement.

Here's un bon lien sur le sujet. Il y en a beaucoup d'autres aussi. Si vous voulez dire "Comment empêcher un utilisateur de commencer à modifier un enregistrement que quelqu'un d'autre est en train de mettre à jour dans un autre GridView", ce serait beaucoup plus compliqué. Il y aurait plusieurs façons de le faire, mais je pense que je chercherais à garder un cache des identifiants des enregistrements qui sont mis à jour, avec des moyens pour expirer les entrées (dans le cas où l'utilisateur a commencé à éditer mais a erré off, a subi une défaillance du système, ou n'a jamais été terminée).

Questions connexes