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):
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?
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!