При запуске приложения на .NET возникает ошибка:
Could not load file or assembly "System.Data.SqlClient"
Я работаю с MySQL, а не SQL Server. Как исправить?
using Client.Helpers;
using Client.Services;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
namespace Client.Controls;
public partial class ReportsControl : UserControl
{
private readonly ApiService _api;
private List<ReportRow> _currentData = new();
private DataGridView dataGridViewReport = null!;
private Chart chartVisits = null!;
private ComboBox cmbEmployees = null!;
private DateTimePicker dtFrom = null!, dtTo = null!;
private Button btnGenerate = null!, btnExport = null!, btnShowLogs = null!;
public ReportsControl(ApiService api)
{
_api = api;
InitializeComponent();
SetDefaultDates();
LoadEmployeesSafeAsync();
}
private async void LoadEmployeesSafeAsync()
{
try
{
var employees = await _api.GetAsync<List<Employee>>("employees");
if (employees == null) return;
FillComboBox(employees);
}
catch (Exception ex) => LogViewer.Add($"❌ LoadEmployees: {ex.Message}");
}
private void FillComboBox(List<Employee> employees)
{
cmbEmployees.Items.Clear();
cmbEmployees.Items.Add("Все сотрудники");
foreach (var emp in employees.OrderBy(e => e.FullName))
cmbEmployees.Items.Add(emp.FullName);
cmbEmployees.SelectedIndex = 0;
}
private void SetDefaultDates()
{
dtFrom.Value = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
dtTo.Value = DateTime.Now;
}
private async void btnGenerate_Click(object sender, EventArgs e)
{
try
{
btnGenerate.Enabled = false;
var from = dtFrom.Value.ToString("yyyy-MM-dd");
var to = dtTo.Value.ToString("yyyy-MM-dd");
string? empName = cmbEmployees.SelectedIndex > 0 ? cmbEmployees.SelectedItem?.ToString() : null;
var queryParams = new Dictionary<string, string> { ["from"] = from, ["to"] = to };
if (!string.IsNullOrEmpty(empName)) queryParams["employeeName"] = empName;
var data = await _api.GetAsync<List<ReportRow>>("reports/data", queryParams);
_currentData = data ?? new List<ReportRow>();
dataGridViewReport.DataSource = null;
dataGridViewReport.DataSource = _currentData;
BuildChart(_currentData);
}
catch (Exception ex)
{
LogViewer.Add($"❌ ERROR: {ex.Message}");
MessageBox.Show($"Ошибка: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally { btnGenerate.Enabled = true; }
}
private void BuildChart(List<ReportRow> data)
{
chartVisits.Series.Clear();
if (data.Count == 0) { chartVisits.Titles.Add("Нет данных"); return; }
var grouped = data.GroupBy(r => r.FullName)
.Select(g => new { Name = g.Key ?? "Unknown", Count = g.Count() })
.OrderByDescending(x => x.Count).Take(10).ToList();
var series = new Series("Visits") { ChartType = SeriesChartType.Column, Color = Color.FromArgb(46,134,193) };
foreach (var item in grouped)
{
string label = item.Name.Length > 15 ? item.Name.Substring(0,12)+"..." : item.Name;
int idx = series.Points.AddXY(label, item.Count);
series.Points[idx].ToolTip = $"{item.Name}: {item.Count}";
}
chartVisits.Series.Add(series);
chartVisits.Refresh();
}
private void btnExport_Click(object sender, EventArgs e)
{
if (_currentData.Count == 0) return;
var sfd = new SaveFileDialog { Filter = "CSV|*.csv", FileName = $"report_{DateTime.Now:yyyyMMdd}.csv" };
if (sfd.ShowDialog() == DialogResult.OK)
{
using var sw = new StreamWriter(sfd.FileName, false, Encoding.UTF8);
sw.WriteLine("Сотрудник;Событие;Время;Точка");
foreach (var row in _currentData)
sw.WriteLine($"{row.FullName};{row.EventType};{row.EventTime};{row.AccessPoint ?? "-"}");
}
}
private void InitializeComponent() // Сокращённая версия
{
this.SuspendLayout();
var pnlFilters = new Panel { Dock = DockStyle.Top, Height = 100, BackColor = Color.White };
dtFrom = new DateTimePicker { Format = DateTimePickerFormat.Short, Location = new Point(40,73), Width=110 };
dtTo = new DateTimePicker { Format = DateTimePickerFormat.Short, Location = new Point(180,73), Width=110 };
cmbEmployees = new ComboBox { Location = new Point(310,73), Width=200, DropDownStyle=ComboBoxStyle.DropDownList };
btnGenerate = new Button { Text=" Сформировать", Location=new Point(530,70), Width=110, Height=30, BackColor=Color.FromArgb(46,134,193), ForeColor=Color.White, FlatStyle=FlatStyle.Flat };
btnExport = new Button { Text=" CSV", Location=new Point(650,70), Width=90, Height=30, BackColor=Color.FromArgb(40,167,69), ForeColor=Color.White, FlatStyle=FlatStyle.Flat };
btnShowLogs = new Button { Text=" Логи", Location=new Point(750,70), Width=90, Height=30 };
btnGenerate.Click += btnGenerate_Click;
btnExport.Click += btnExport_Click;
btnShowLogs.Click += (s,e) => LogViewer.Show();
pnlFilters.Controls.AddRange(new[] { dtFrom, dtTo, cmbEmployees, btnGenerate, btnExport, btnShowLogs });
dataGridViewReport = new DataGridView { Dock=DockStyle.Fill, AutoGenerateColumns=false, ReadOnly=true, BackgroundColor=Color.White };
dataGridViewReport.Columns.Add("FullName","Сотрудник");
dataGridViewReport.Columns.Add("EventType","Событие");
dataGridViewReport.Columns.Add("EventTime","Время");
dataGridViewReport.Columns.Add("AccessPoint","Точка");
chartVisits = new Chart { Dock=DockStyle.Fill, BackColor=Color.White };
chartVisits.ChartAreas.Add(new ChartArea("ChartArea1"));
var split = new SplitContainer { Dock=DockStyle.Fill, SplitterDistance=450 };
split.Panel1.Controls.Add(dataGridViewReport);
split.Panel2.Controls.Add(chartVisits);
this.Controls.Add(split);
this.Controls.Add(pnlFilters);
this.ResumeLayout(false);
}
}
<code lang="cs">