Search code examples
c#sql-serverdataadapter.net-3.5

DataAdapter does not delete database row


I'm working on a very old project with .Net Framework 3.5 using DataSets and SQL Server. So I need to do something.

I'm facing a problem with deleting rows from database. Here is my test code:

using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TypedDataSetTest.UsersDataSetTableAdapters;

namespace TypedDataSetTest
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var userAdapter = new UserTableAdapter())
            {
                var users = userAdapter.GetData();

                userAdapter.DeleteAll();
                users.Clear();    

                PopulateUsers(users, userAdapter);
                PrintData(users);

                var user1 = users.Single(user => user.Name == "user1");
                user1.Delete();
                user1.AcceptChanges();
                //users.AcceptChanges();
                //userAdapter.Update(user1);

                var user2 = users.Single(user => user.Name == "user2");
                user2.Name = "user3";
                //mary.AcceptChanges();
                //users.AcceptChanges();
                //userAdapter.Update(user2);

                userAdapter.Update(users);

                PrintData(users);
            }

            Console.ReadLine();
        }

        private static void PrintData(UsersDataSet.UserDataTable users)
        {
            users.ToList().ForEach(user => Console.WriteLine("{0} {1} {2} {3:dd/MM/yyyy} {4}", user.Id, string.IsNullOrWhiteSpace(user.Field<string>("Name")) ? "" : user.Field<string>("Name"), user.Surname, user.Field<DateTime?>("BirthDate").GetValueOrDefault(), user.TIN));
            Console.WriteLine();
        }


        private static void PopulateUsers(UsersDataSet.UserDataTable users, UserTableAdapter userAdapter)
        {
            var user1 = users.NewUserRow();
            user1.Name = "user1";
            user1.Surname = "user1 surname";
            user1.BirthDate = new DateTime(1970, 12, 03);
            user1.TIN = "123123";

            var user2 = users.NewUserRow();
            user2.Name = "user2";
            user2.Surname = "user2 surname";
            user2.BirthDate = new DateTime(1974, 2, 14);
            user2.TIN = "456456";

            var newUsers = new UsersDataSet.UserRow[] { user1, user2 };
            userAdapter.Connection.Open();

            newUsers.ToList().ForEach(user =>
            {
                if (userAdapter.InsertUser(user) > 0)
                {
                    users.AddUserRow(user);
                    users.AcceptChanges();
                }                
            });

            userAdapter.Connection.Close();
        }
    }
}

All database actions are performed through stored procedures:

CREATE PROCEDURE [dbo].[User_Delete]
    (@Id INT)
AS
    --set nocount on;
    DELETE FROM [dbo].[User] 
    WHERE (Id = @Id);
GO

CREATE PROCEDURE [dbo].[User_DeleteAll]
AS
    SET NOCOUNT ON;

    DELETE FROM [dbo].[User];
GO

CREATE PROCEDURE [dbo].[User_Insert](
    @Name NVARCHAR(50),
    @Surname NVARCHAR(50),
    @BirthDate DATETIM2(7),
    @TIN NVARCHAR(50))
AS
    SET NOCOUNT ON;

    INSERT INTO [dbo].[User] ([Name], [Surname], [BirthDate], [TIN])
    VALUES (@Name, @Surname, @BirthDate, @TIN);

    SELECT SCOPE_IDENTITY();   
GO

CREATE PROCEDURE [dbo].[User_SelectAll]
AS 
    SET NOCOUNT ON;

    SELECT    
        [Id], [Name], [Surname], [BirthDate], [TIN]
    FROM 
        [dbo].[User];
GO

CREATE PROCEDURE [dbo].[User_Update]
    (@Id INT,
     @Name NVARCHAR(50),
     @Surname NVARCHAR(50),
     @BirthDate DATETIME2(7),
     @TIN NVARCHAR(50))
AS
     SET NOCOUNT ON;

     UPDATE [dbo].[User]
     SET [Name] = @Name,
         [Surname] = @Surname,
         [BirthDate] = @BirthDate,
         [TIN] = @TIN
     WHERE (Id = @Id)
GO

Also here is my xsd and table-adapter info, all by the book(I think):

enter image description here

This code seems to work on console, user1 is deleted from the DataTable and user2 name is changed to "user3".

But in database table, only the change of name is persisted. User1 was not deleted.

If I call userAdapter.Update(user1); everything is fine. I've tried several things found on Internet but nothing seems to work.

It looks like userAdapter cannot locate the DeleteCommand for the user1 row. There is no exception, just it does not delete it from the database.

Am I missing something? Is there something I'm doing wrong?


Solution

  • I found the problem. This code works fine:

    using (var userAdapter = new UserTableAdapter())
                {
                    var users = userAdapter.GetData();
    
                    userAdapter.DeleteAll();
                    users.Clear();    
    
                    PopulateUsers(users, userAdapter);
                    PrintData(users);
    
                    var user1 = users.Single(user => user.Name == "user1");
                    var user2 = users.Single(user => user.Name == "user2");
    
                    user1.Delete(); 
                    user2.Name = "user3";
    
                    userAdapter.Update(users);
    
                    PrintData(users);
                }
    

    In the previous version, I could not locate user2 if user1 was "marked" as to-delete so I called AcceptChanges to be able to iterate through users data-table to get user2. Calling user1.AcceptChanges(); changed the status of user1 row, so there is no to-delete information.

    So everything is fine!