Dreamine.Database.SqlServer 1.0.1
Dreamine.Database.SqlServer 데이터베이스 기능과 관련 API를 제공합니다.
로딩중...
검색중...
일치하는것 없음
SqlServerDatabaseProvider.cs
이 파일의 문서화 페이지로 가기
1using Dreamine.Database.Abstractions;
2using Dreamine.Database.Core.Mapping;
3using Dreamine.Database.Core.Providers;
4using Microsoft.Data.SqlClient;
5using System.Data;
6
8
17public sealed class SqlServerDatabaseProvider : DatabaseProviderBase
18{
51 public SqlServerDatabaseProvider(string connectionString)
52 : base(connectionString)
53 {
54 }
55
64 public override DatabaseProviderKind Kind => DatabaseProviderKind.SqlServer;
65
74 public override void EnsureDatabaseExists()
75 {
76 var builder = new SqlConnectionStringBuilder(ConnectionString);
77 var databaseName = builder.InitialCatalog;
78 if (string.IsNullOrWhiteSpace(databaseName))
79 {
80 base.EnsureDatabaseExists();
81 return;
82 }
83
84 builder.InitialCatalog = "master";
85
86 using var connection = new SqlConnection(builder.ConnectionString);
87 connection.Open();
88
89 using var command = connection.CreateCommand();
90 command.CommandText = $"""
91 IF DB_ID(N'{EscapeSqlLiteral(databaseName)}') IS NULL
92 CREATE DATABASE {QuoteIdentifier(databaseName)}
93 """;
94 command.ExecuteNonQuery();
95 }
96
121 public override async Task EnsureDatabaseExistsAsync(CancellationToken cancellationToken = default)
122 {
123 var builder = new SqlConnectionStringBuilder(ConnectionString);
124 var databaseName = builder.InitialCatalog;
125 if (string.IsNullOrWhiteSpace(databaseName))
126 {
127 await base.EnsureDatabaseExistsAsync(cancellationToken).ConfigureAwait(false);
128 return;
129 }
130
131 builder.InitialCatalog = "master";
132
133 await using var connection = new SqlConnection(builder.ConnectionString);
134 await connection.OpenAsync(cancellationToken).ConfigureAwait(false);
135
136 await using var command = connection.CreateCommand();
137 command.CommandText = $"""
138 IF DB_ID(N'{EscapeSqlLiteral(databaseName)}') IS NULL
139 CREATE DATABASE {QuoteIdentifier(databaseName)}
140 """;
141 await command.ExecuteNonQueryAsync(cancellationToken).ConfigureAwait(false);
142 }
143
184 public override bool IsTableExists(string tableName)
185 {
186 ArgumentException.ThrowIfNullOrWhiteSpace(tableName);
187
188 const string sql = """
189 SELECT COUNT(1)
190 FROM INFORMATION_SCHEMA.TABLES
191 WHERE TABLE_NAME = @TableName
192 """;
193
194 return ExecuteScalar<int>(sql, new { TableName = tableName }) > 0;
195 }
196
245 public override async Task<bool> IsTableExistsAsync(
246 string tableName,
247 CancellationToken cancellationToken = default)
248 {
249 ArgumentException.ThrowIfNullOrWhiteSpace(tableName);
250
251 const string sql = """
252 SELECT COUNT(1)
253 FROM INFORMATION_SCHEMA.TABLES
254 WHERE TABLE_NAME = @TableName
255 """;
256
257 var count = await ExecuteScalarAsync<int>(sql, new { TableName = tableName }, cancellationToken)
258 .ConfigureAwait(false);
259 return count > 0;
260 }
261
278 protected override IDbConnection CreateConnection()
279 {
280 return new SqlConnection(ConnectionString);
281 }
282
323 protected override string QuoteIdentifier(string identifier)
324 {
325 ArgumentException.ThrowIfNullOrWhiteSpace(identifier);
326 return "[" + identifier.Replace("]", "]]", StringComparison.Ordinal) + "]";
327 }
328
353 protected override string BuildCreateTableSql(DatabaseEntityMap map)
354 {
355 var columns = map.Properties.Select(property =>
356 {
357 var sql = $"{QuoteIdentifier(property.ColumnName)} {GetSqlType(property)}";
358 if (property.IsKey)
359 {
360 sql += property.IsGenerated ? " IDENTITY(1,1) PRIMARY KEY" : " PRIMARY KEY";
361 }
362
363 return sql;
364 });
365
366 return $"""
367 IF OBJECT_ID(N'{map.TableName}', N'U') IS NULL
368 CREATE TABLE {QuoteIdentifier(map.TableName)} ({string.Join(", ", columns)})
369 """;
370 }
371
396 protected override string GetSqlType(DatabasePropertyMap property)
397 {
398 var type = property.PropertyType;
399
400 if (type == typeof(bool))
401 {
402 return "BIT";
403 }
404
405 if (type == typeof(byte) || type == typeof(short))
406 {
407 return "SMALLINT";
408 }
409
410 if (type == typeof(int))
411 {
412 return "INT";
413 }
414
415 if (type == typeof(long))
416 {
417 return "BIGINT";
418 }
419
420 if (type == typeof(float))
421 {
422 return "REAL";
423 }
424
425 if (type == typeof(double))
426 {
427 return "FLOAT";
428 }
429
430 if (type == typeof(decimal))
431 {
432 return "DECIMAL(18, 4)";
433 }
434
435 if (type == typeof(DateTime) || type == typeof(DateTimeOffset))
436 {
437 return "DATETIME2";
438 }
439
440 if (type == typeof(byte[]))
441 {
442 return "VARBINARY(MAX)";
443 }
444
445 return "NVARCHAR(MAX)";
446 }
447
472 private static string EscapeSqlLiteral(string value)
473 {
474 return value.Replace("'", "''", StringComparison.Ordinal);
475 }
476}
override string GetSqlType(DatabasePropertyMap property)
override async Task EnsureDatabaseExistsAsync(CancellationToken cancellationToken=default)
override async Task< bool > IsTableExistsAsync(string tableName, CancellationToken cancellationToken=default)