![](/img/trans.png)
[英]Entity Framework Core, execute raw SQL and parameterize table name
[英]Entity Framework Core - Execute raw sql - Same code for SQL/SQLite
在我的LogService中插入新的異常時,我目前使用兩種不同的Connections類型(正常使用的SQLConnection和集成測試的SqliteConnection)。
因為我無權訪問數據庫上下文類,所以必須使用原始sql插入新實體,(我只有數據庫連接字符串)。
在運行集成測試時,由於實體關系,我必須在內存數據庫中使用SQLite(SQL在內存中不支持此功能)。
protected async Task InsertException(DateTime utcNow, LogLevel logLevel, EventId eventId, string state, Exception exception, CategoryAppSettings categoryAppSettings, string caller, string ipAddress, int? userId, int? organisationId, string requestId)
{
string stackTrace = exception?.StackTrace;
string query =
"INSERT INTO [Exception] " +
"(" +
"[Created]" +
",[EventId]" +
",[IpAddress]" +
",[LogLevel]" +
",[Message]" +
",[Source]" +
",[StackTrace]" +
",[State]" +
",[UserId]" +
",[OrganisationId]" +
",[RequestId]" +
")" +
"VALUES" +
"(" +
"@Created" +
",@EventId" +
",@IpAddress" +
",@LogLevel" +
",@Message" +
",@Source" +
",@StackTrace" +
",@State" +
",@UserId" +
",@OrganisationId" +
",@RequestId" +
")";
Dictionary<string, object> parameters = new Dictionary<string, object>
{
{ "@Created", utcNow },
{ "@EventId", eventId.ToString() ?? (object)DBNull.Value },
{ "@IpAddress", ipAddress ?? (object)DBNull.Value },
{ "@LogLevel", logLevel.ToString() ?? (object)DBNull.Value },
{ "@Message", exception?.Message ?? (object)DBNull.Value },
{ "@Source", caller ?? (object)DBNull.Value },
{ "@StackTrace", stackTrace?.Trim() ?? (object)DBNull.Value },
{ "@State", state ?? (object)DBNull.Value },
{ "@UserId", userId ?? (object)DBNull.Value },
{ "@OrganisationId", organisationId ?? (object)DBNull.Value },
{ "@RequestId", requestId ?? (object)DBNull.Value },
};
try
{
if (_hostingEnvironment.EnvironmentName == "Test")
{
using (SqliteConnection sqlConnection = new SqliteConnection($"Data Source={_logAppSettings.ConnectionStrings.Database};Mode=Memory;Cache=Shared;"))
{
using (SqliteCommand sqlCommand = new SqliteCommand(query, sqlConnection))
{
foreach (var parameter in parameters)
{
sqlCommand.Parameters.Add(new SqliteParameter(parameter.Key, parameter.Value));
}
sqlConnection.Open();
await sqlCommand.ExecuteNonQueryAsync();
}
}
}
else
{
using (SqlConnection sqlConnection = new SqlConnection(_logAppSettings.ConnectionStrings.Database))
{
using (SqlCommand sqlCommand = new SqlCommand(query, sqlConnection))
{
foreach (var parameter in parameters)
{
sqlCommand.Parameters.Add(new SqlParameter(parameter.Key, parameter.Value));
}
sqlConnection.Open();
await sqlCommand.ExecuteNonQueryAsync();
}
}
}
}
catch (Exception ex)
{
ExceptionModel exceptionModel = new ExceptionModel()
{
StackTrace = ex?.StackTrace,
Message = ex?.Message,
InnerException = ex?.InnerException.ToString()
};
LogModel log = new LogModel()
{
Created = $"{utcNow:yyyy-MM-dd HH:mm}",
LogLevel = LogLevel.Error.ToString(),
EventId = LogEvents.Log,
Source = ex.Source,
IpAddress = ipAddress,
UserId = userId,
OrganisationId = organisationId,
State = "An unexpected error occured while trying to insert new exception.",
Exception = exceptionModel,
RequestId = requestId
};
InsertLog(utcNow, log, categoryAppSettings);
}
}
如您所見,我正在使用兩種不同的數據庫類型,兩種不同的連接類型。 我真的不喜歡它,因為您必須自定義代碼以使測試變得更簡單!
兩個數據庫都可以有一種連接類型嗎?
我看過“ Entity SQL”,但是我不認為它在Entity Framework Core中受支持,並且有點過時。
可能不是您想要的,但是您可以通過使用DbConnection而不是SQLConnection避免代碼加倍。 您可以在其他任何地方定義DbConnectionType,例如:
Type connectionType = _hostingEnvironment.EnvironmentName == "Test" ? typeof(SqliteConnection) : typeof(SqlConnection);
// If you switch the Connection String outside too, it should work:
string connectionString = _hostingEnvironment.EnvironmentName == "Test" ? $"Data Source={_logAppSettings.ConnectionStrings.Database};Mode=Memory;Cache=Shared;" : _logAppSettings.ConnectionStrings.Database;
using (DbConnection sqlConnection = Activator.CreateInstance(connectionType, new object[] {connectionString}) as DbConnection)
{
using (DbCommand sqlCommand = sqlConnection.CreateCommand())
{
sqlCommand.CommandText = query;
foreach (var parameter in parameters)
{
DbParameter param = sqlCommand.CreateParameter();
param.ParameterName= parameter.Key;
param.Value=parameter.Value;
sqlCommand.Parameters.Add(param );
}
sqlConnection.Open();
await sqlCommand.ExecuteNonQueryAsync();
}
}
}
我希望這可以幫助你!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.