首先创建WPF项目,在nuget安装包中下载System.Data.SqlClient
配置数据库的连接字符串来连接数据库
创建示例数据库,拥有两个table:
CREATE TABLE [dbo].[Customers] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Name] NCHAR (50) NOT NULL,
[IdNumber] NCHAR (18) NOT NULL,
[Address] NCHAR (100) NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
CREATE TABLE [dbo].Appointments
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY,
[Time] DATETIME NOT NULL,
[CustomerId] INT NOT NULL,
CONSTRAINT [FK_Appointments_Customers] FOREIGN KEY (CustomerId) REFERENCES Customers(Id)
)
实现UI界面对于数据库数据的显示
MainWindow.xaml.cs
public partial class MainWindow : Window
{
private SqlConnection _sqlConnection;
public MainWindow()
{
InitializeComponent();
string connectionString = "数据库连接字符串";//填入自己的数据库连接字符串
_sqlConnection = new SqlConnection(connectionString);
ShowCustomers();
}
//访问数据库
private void ShowCustomers()
{
//防止数据库死机等意外导致以下操作全部失败,系统崩溃
try
{
SqlDataAdapter adapter = new SqlDataAdapter("select * from Customers", _sqlConnection);
//数据库适配器可以帮我们解决数据库的打开关闭
using (adapter)
{
DataTable customerTable = new DataTable();
adapter.Fill(customerTable);
customerList.DisplayMemberPath = "Name";
//绑定数据
customerList.SelectedValuePath = "Id";
//绑定数据源
customerList.ItemsSource = customerTable.DefaultView;
}
}catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private void customerList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
try
{
//查询Appointments.CustomerId = Customers.Id且为参数传入的Id,@为参数引导
string query = "select * from Appointments join Customers on Appointments.CustomerId = Customers.Id where Customers.Id = @CustomerId";
var customerId = customerList.SelectedValue;
//用于删除预约信息时,会先删除customerId,造成customerId为空情况
if (customerId == null)
{
appointmentList.ItemsSource = null;
return;
}
SqlCommand sqlCommand = new SqlCommand(query, _sqlConnection);
SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(sqlCommand);
//键值对数据在此聚合
sqlCommand.Parameters.AddWithValue("@CustomerId", customerId);
using (sqlDataAdapter)
{
DataTable appointmentTable = new DataTable();
sqlDataAdapter.Fill(appointmentTable);
appointmentList.DisplayMemberPath = "Time";
//绑定数据
appointmentList.SelectedValuePath = "Id";
//绑定数据源
appointmentList.ItemsSource = appointmentTable.DefaultView;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
注意,要使用一个try,catch来包含操作,防止因为数据库卡顿死机等问题造成系统瘫痪
示例UI界面如下,注意UI界面的命名与后面函数名的对应
<Grid>
<Label Content="客户列表" HorizontalAlignment="Left" Margin="67,35,0,0" VerticalAlignment="Top" Width="219"/>
<ListBox d:ItemsSource="{d:SampleData ItemCount=5}" Margin="67,91,730,202" Name="customerList" SelectionChanged="customerList_SelectionChanged"/>
<Label Content="预约记录" HorizontalAlignment="Left" Margin="590,30,0,0" VerticalAlignment="Top" Width="219"/>
<ListBox d:ItemsSource="{d:SampleData ItemCount=5}" Margin="590,91,191,202" Name="appointmentList"/>
<Button Content="删除客户" HorizontalAlignment="Left" Margin="67,388,0,0" VerticalAlignment="Top" RenderTransformOrigin="6.484,2.324" Width="203" Click="DeleteCustomer_Click"/>
<Button Content="取消预约" HorizontalAlignment="Left" Margin="590,388,0,0" VerticalAlignment="Top" Width="219" Click="CancelAppointment_Click"/>
<TextBox Name="NameTextBox" HorizontalAlignment="Left" Margin="23,495,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
<TextBox Name="IdTextBox" HorizontalAlignment="Left" Margin="148,495,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
<TextBox Name="AddressTextBox" HorizontalAlignment="Left" Margin="278,495,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
<Label Content="姓名 " HorizontalAlignment="Left" Margin="23,466,0,0" VerticalAlignment="Top"/>
<Label Content="身份证号" HorizontalAlignment="Left" Margin="148,466,0,0" VerticalAlignment="Top"/>
<Label Content="住址" HorizontalAlignment="Left" Margin="278,466,0,0" VerticalAlignment="Top" RenderTransformOrigin="-1.766,1.797"/>
<Label Content="添加客户信息" HorizontalAlignment="Left" Margin="23,436,0,0" VerticalAlignment="Top"/>
<Button Content="添加客户" HorizontalAlignment="Left" Margin="23,533,0,0" VerticalAlignment="Top" Click="AddCustomer_Click"/>
<DatePicker Name="AppointmentDatePicker" HorizontalAlignment="Left" Margin="590,479,0,0" VerticalAlignment="Top"/>
<Label Content="添加预约日期" HorizontalAlignment="Left" Margin="590,436,0,0" VerticalAlignment="Top"/>
<Button Content="预约" HorizontalAlignment="Left" Margin="590,523,0,0" VerticalAlignment="Top" Click="AddAppointment_Click"/>
<Button Content="更新客户资料" HorizontalAlignment="Left" Margin="163,538,0,0" VerticalAlignment="Top" Click="UpdateCustomer_Click"/>
Grid>
1.实现删除
对于Appointments表的删除,只需要直接delete即可以完成
示例代码如下
private void CancelAppointment_Click(object sender, RoutedEventArgs e)
{
try
{
var sql = "delete from Appointments where Id = @AppointmentId";
var appointmentId = appointmentList.SelectedValue;
SqlCommand sqlCommand = new SqlCommand(sql, _sqlConnection);
sqlCommand.Parameters.AddWithValue("@AppointmentId", appointmentId);
_sqlConnection.Open();
//执行删除
sqlCommand.ExecuteScalar();
MessageBox.Show("取消预约成功!");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
finally
{
_sqlConnection.Close();
//刷新预约列表
customerList_SelectionChanged(null, null);
}
}
对于Customers表的删除,由于Appointments表的CustomerId为对应Customers表Id的外键,因此删除时,需要先删除Appointments数据,再删除Customers表的数据
private void DeleteCustomer_Click(object sender, RoutedEventArgs e)
{
try
{
string sqlDelteAppointment = "delete from Appointments where CustomerId = @CustomerId";
string sqlDeleteCustomer = "delete from Customers where Id = @CustomerId";
var customerId = customerList.SelectedValue;
SqlCommand sqlCommand1 = new SqlCommand( sqlDelteAppointment, _sqlConnection);
SqlCommand sqlCommand2 = new SqlCommand( sqlDeleteCustomer, _sqlConnection);
sqlCommand1.Parameters.AddWithValue("@CustomerId", customerId);
sqlCommand2.Parameters.AddWithValue("@CustomerId", customerId);
_sqlConnection.Open();
sqlCommand1.ExecuteScalar();
sqlCommand2.ExecuteScalar();
MessageBox.Show("删除用户成功!");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
finally
{
_sqlConnection.Close();
ShowCustomers();
customerList_SelectionChanged(null, null);
}
}
2.实现添加
添加时,注意appointments的Id是取自customers的selectedvalue中
private void AddCustomer_Click(object sender, RoutedEventArgs e)
{
try
{
var sql = "insert into Customers values(@name, @id, @address)";
SqlCommand sqlCommand = new SqlCommand(sql, _sqlConnection);
sqlCommand.Parameters.AddWithValue("@name", NameTextBox.Text);
sqlCommand.Parameters.AddWithValue("@id", IdTextBox.Text);
sqlCommand.Parameters.AddWithValue("@address", AddressTextBox.Text);
_sqlConnection.Open();
sqlCommand.ExecuteScalar();
MessageBox.Show("添加用户信息成功!");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
finally
{
_sqlConnection.Close();
ShowCustomers();
}
}
private void AddAppointment_Click(object sender, RoutedEventArgs e)
{
try
{
var sql = "insert into Appointments values(@date, @customerId)";
SqlCommand sqlCommand = new SqlCommand(sql, _sqlConnection);
sqlCommand.Parameters.AddWithValue("@date", AppointmentDatePicker.Text);
sqlCommand.Parameters.AddWithValue("@customerId", customerList.SelectedValue);
_sqlConnection.Open();
sqlCommand.ExecuteScalar();
MessageBox.Show("用户信息更新成功!");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
finally
{
_sqlConnection.Close();
customerList_SelectionChanged(null, null);
}
}
三、实现修改
实现修改,需要显示出项目数据,因此可以利用添加数据时的输入框来显示数据并完成修改,因此在 customerList_SelectionChanged函数中实现输入框显示数据
DataRowView selectItem = customerList.SelectedItem as DataRowView;
NameTextBox.Text = selectItem["Name"] as string;
IdTextBox.Text = selectItem["IdNumber"] as string;
AddressTextBox.Text = selectItem["Address"] as string;
那么就可以直接将输入框的数据接收传入修改
private void UpdateCustomer_Click(object sender, RoutedEventArgs e)
{
try
{
var sql = "update Customers set Name=@name, IdNumber=@idNumber, Address=@address where Id=@customerId";
SqlCommand sqlCommand = new SqlCommand(sql, _sqlConnection);
sqlCommand.Parameters.AddWithValue("@name", NameTextBox.Text.Trim());//trim用来消除空格
sqlCommand.Parameters.AddWithValue("@idNumber", IdTextBox.Text.Trim());
sqlCommand.Parameters.AddWithValue("@address", AddressTextBox.Text.Trim());
sqlCommand.Parameters.AddWithValue("@customerId", customerList.SelectedValue);
_sqlConnection.Open();
sqlCommand.ExecuteScalar();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
finally
{
_sqlConnection.Close();
ShowCustomers();
}
}
由于对于数据库的操作是具有风险的,因此一定要将对外操作放进try,catch中,防止因为数据库的死机等意外造成系统的崩溃。
另外,一定要将数据库的关闭操作放置在finally中,防止出现内存泄漏的事故。