using System.Data; using MySql.Data.MySqlClient; using HardwarePerformance.Core.Entities; using Microsoft.Extensions.Configuration; namespace HardwarePerformance.Infrastructure.Data; public class SimpleAppDbContext { private readonly string _connectionString; public SimpleAppDbContext(IConfiguration configuration) { _connectionString = configuration.GetConnectionString("DefaultConnection"); } public async Task TestConnectionAsync() { try { using var connection = new MySqlConnection(_connectionString); await connection.OpenAsync(); return connection.State == ConnectionState.Open; } catch { return false; } } public async Task InitializeDatabaseAsync() { using var connection = new MySqlConnection(_connectionString); await connection.OpenAsync(); // 创建Categories表 var createCategoriesTable = @" CREATE TABLE IF NOT EXISTS Categories ( Id INT AUTO_INCREMENT PRIMARY KEY, Name VARCHAR(100) NOT NULL, Description TEXT, CreatedAt DATETIME DEFAULT CURRENT_TIMESTAMP )"; using var cmd = new MySqlCommand(createCategoriesTable, connection); await cmd.ExecuteNonQueryAsync(); // 创建Products表 var createProductsTable = @" CREATE TABLE IF NOT EXISTS Products ( Id INT AUTO_INCREMENT PRIMARY KEY, Name VARCHAR(200) NOT NULL, Model VARCHAR(100), Manufacturer VARCHAR(100), ImageUrl VARCHAR(500), ReleaseDate DATE, CategoryId INT, CurrentRank INT, CreatedAt DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (CategoryId) REFERENCES Categories(Id) )"; cmd.CommandText = createProductsTable; await cmd.ExecuteNonQueryAsync(); // 创建PerformanceScores表 var createPerformanceScoresTable = @" CREATE TABLE IF NOT EXISTS PerformanceScores ( Id INT AUTO_INCREMENT PRIMARY KEY, ProductId INT NOT NULL, BenchmarkType VARCHAR(50) NOT NULL, Score INT NOT NULL, TestDate DATETIME DEFAULT CURRENT_TIMESTAMP, DataSourceId INT, FOREIGN KEY (ProductId) REFERENCES Products(Id) )"; cmd.CommandText = createPerformanceScoresTable; await cmd.ExecuteNonQueryAsync(); // 创建DataSources表 var createDataSourcesTable = @" CREATE TABLE IF NOT EXISTS DataSources ( Id INT AUTO_INCREMENT PRIMARY KEY, Name VARCHAR(100) NOT NULL, Description TEXT, WebsiteUrl VARCHAR(500), CreatedAt DATETIME DEFAULT CURRENT_TIMESTAMP )"; cmd.CommandText = createDataSourcesTable; await cmd.ExecuteNonQueryAsync(); // 创建Specifications表 var createSpecificationsTable = @" CREATE TABLE IF NOT EXISTS Specifications ( Id INT AUTO_INCREMENT PRIMARY KEY, ProductId INT NOT NULL, Name VARCHAR(100) NOT NULL, Value TEXT NOT NULL, Unit VARCHAR(50), FOREIGN KEY (ProductId) REFERENCES Products(Id) )"; cmd.CommandText = createSpecificationsTable; await cmd.ExecuteNonQueryAsync(); // 创建RankingHistories表 var createRankingHistoriesTable = @" CREATE TABLE IF NOT EXISTS RankingHistories ( Id INT AUTO_INCREMENT PRIMARY KEY, ProductId INT NOT NULL, Rank INT NOT NULL, CategoryId INT NOT NULL, RecordedAt DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (ProductId) REFERENCES Products(Id), FOREIGN KEY (CategoryId) REFERENCES Categories(Id) )"; cmd.CommandText = createRankingHistoriesTable; await cmd.ExecuteNonQueryAsync(); } public async Task SeedInitialDataAsync() { using var connection = new MySqlConnection(_connectionString); await connection.OpenAsync(); // 检查是否已有数据 var checkCategoriesCmd = new MySqlCommand("SELECT COUNT(*) FROM Categories", connection); var categoryCount = Convert.ToInt32(await checkCategoriesCmd.ExecuteScalarAsync()); if (categoryCount > 0) { return; // 已有数据,不需要种子数据 } // 插入Categories var insertCategories = @" INSERT INTO Categories (Name, Description) VALUES ('手机CPU', '移动设备处理器'), ('手机GPU', '移动设备图形处理器'), ('电脑CPU', '桌面和笔记本处理器'), ('电脑GPU', '桌面和笔记本图形处理器')"; using var cmd = new MySqlCommand(insertCategories, connection); await cmd.ExecuteNonQueryAsync(); // 插入DataSources var insertDataSources = @" INSERT INTO DataSources (Name, Description, WebsiteUrl) VALUES ('Geekbench', '处理器和内存性能测试', 'https://www.geekbench.com'), ('3DMark', '图形和游戏性能测试', 'https://www.3dmark.com'), ('AnTuTu', '移动设备综合性能测试', 'https://www.antutu.com')"; cmd.CommandText = insertDataSources; await cmd.ExecuteNonQueryAsync(); // 插入示例产品 var insertProducts = @" INSERT INTO Products (Name, Model, Manufacturer, ReleaseDate, CategoryId, CurrentRank) VALUES ('Apple A17 Pro', 'A17 Pro', 'Apple', '2023-09-12', 1, 1), ('Snapdragon 8 Gen 3', 'SM8650-AB', 'Qualcomm', '2023-10-24', 1, 2), ('Intel Core i9-13900K', 'Core i9-13900K', 'Intel', '2022-10-20', 3, 1), ('AMD Ryzen 9 7950X', 'Ryzen 9 7950X', 'AMD', '2022-09-27', 3, 2), ('NVIDIA GeForce RTX 4090', 'RTX 4090', 'NVIDIA', '2022-10-12', 4, 1), ('AMD Radeon RX 7900 XTX', 'RX 7900 XTX', 'AMD', '2022-12-13', 4, 2)"; cmd.CommandText = insertProducts; await cmd.ExecuteNonQueryAsync(); // 插入性能分数 var insertPerformanceScores = @" INSERT INTO PerformanceScores (ProductId, BenchmarkType, Score, DataSourceId) VALUES (1, 'Geekbench Single-Core', 2900, 1), (1, 'Geekbench Multi-Core', 7200, 1), (2, 'Geekbench Single-Core', 2300, 1), (2, 'Geekbench Multi-Core', 7400, 1), (3, 'Geekbench Single-Core', 3200, 1), (3, 'Geekbench Multi-Core', 24000, 1), (4, 'Geekbench Single-Core', 2600, 1), (4, 'Geekbench Multi-Core', 26000, 1)"; cmd.CommandText = insertPerformanceScores; await cmd.ExecuteNonQueryAsync(); // 插入规格参数 var insertSpecifications = @" INSERT INTO Specifications (ProductId, Name, Value, Unit) VALUES (1, '工艺', '3nm', null), (1, '核心数', '6', '个'), (1, '线程数', '6', '个'), (2, '工艺', '4nm', null), (2, '核心数', '8', '个'), (2, '线程数', '8', '个'), (3, '工艺', 'Intel 7', null), (3, '核心数', '24', '个'), (3, '线程数', '32', '个'), (4, '工艺', '5nm', null), (4, '核心数', '16', '个'), (4, '线程数', '32', '个')"; cmd.CommandText = insertSpecifications; await cmd.ExecuteNonQueryAsync(); } public async Task> GetCategoriesAsync() { var categories = new List(); using var connection = new MySqlConnection(_connectionString); await connection.OpenAsync(); using var cmd = new MySqlCommand("SELECT * FROM Categories", connection); using var reader = await cmd.ExecuteReaderAsync(); while (await reader.ReadAsync()) { categories.Add(new { Id = reader.GetInt32("Id"), Name = reader.GetString("Name"), Description = reader.IsDBNull("Description") ? null : reader.GetString("Description"), CreatedAt = reader.GetDateTime("CreatedAt") }); } return categories; } public async Task> GetProductsAsync(int categoryId = 0, int page = 1, int pageSize = 10) { var products = new List(); using var connection = new MySqlConnection(_connectionString); await connection.OpenAsync(); var offset = (page - 1) * pageSize; var query = categoryId > 0 ? $"SELECT p.*, c.Name as CategoryName FROM Products p LEFT JOIN Categories c ON p.CategoryId = c.Id WHERE p.CategoryId = {categoryId} LIMIT {pageSize} OFFSET {offset}" : $"SELECT p.*, c.Name as CategoryName FROM Products p LEFT JOIN Categories c ON p.CategoryId = c.Id LIMIT {pageSize} OFFSET {offset}"; using var cmd = new MySqlCommand(query, connection); using var reader = await cmd.ExecuteReaderAsync(); while (await reader.ReadAsync()) { products.Add(new { Id = reader.GetInt32("Id"), Name = reader.GetString("Name"), Model = reader.IsDBNull("Model") ? null : reader.GetString("Model"), Manufacturer = reader.IsDBNull("Manufacturer") ? null : reader.GetString("Manufacturer"), ImageUrl = reader.IsDBNull("ImageUrl") ? null : reader.GetString("ImageUrl"), ReleaseDate = reader.IsDBNull("ReleaseDate") ? (DateTime?)null : reader.GetDateTime("ReleaseDate"), CategoryId = reader.IsDBNull("CategoryId") ? (int?)null : reader.GetInt32("CategoryId"), CategoryName = reader.IsDBNull("CategoryName") ? null : reader.GetString("CategoryName"), CurrentRank = reader.IsDBNull("CurrentRank") ? (int?)null : reader.GetInt32("CurrentRank"), CreatedAt = reader.GetDateTime("CreatedAt") }); } return products; } }