Указатель NULL
- это тот, который указывает на никуда. Когда вы разыскиваете указатель p
, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p
является нулевым указателем, местоположение, хранящееся в p
, является nowhere
, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception
.
В общем, это потому, что что-то не было правильно инициализировано.
Решил эту проблему, немного обойдя дома и построив новую цепочку соединений для тестирования с ADO. Все еще включает использование try catch, но это намного быстрее:
private bool TestConnection()
{
EntityConnectionStringBuilder b = new EntityConnectionStringBuilder();
ConnectionStringSettings entityConString = ConfigurationManager.ConnectionStrings["MyEntityConnectionString"];
b.ConnectionString = entityConString.ConnectionString;
string providerConnectionString = b.ProviderConnectionString;
SqlConnectionStringBuilder conStringBuilder = new SqlConnectionStringBuilder();
conStringBuilder.ConnectionString = providerConnectionString;
conStringBuilder.ConnectTimeout = 1;
string constr = conStringBuilder.ConnectionString;
using (SqlConnection conn = new SqlConnection(constr))
{
try
{
conn.Open();
return true;
}
catch
{
return false;
}
}
}
Простейшее:
private bool TestConnection()
{
var db = new MyEntityCollection();
int oldTimeOut = db.CommandTimeout;
try
{
db.CommandTimeout = 1;
db.Connection.Open(); // check the database connection
return true;
}
catch
{
return false;
}
finally
{
db.CommandTimeout = oldTimeOut;
}
}
Обновление для EF6:
using System.Data.Common;
...
public bool TestConnection() {
using (var db = new MyEntityCollection()) {
DbConnection conn = db.Database.Connection;
try {
conn.Open(); // check the database connection
return true;
}
catch {
return false;
}
}
}
В моем приложении пользователь может изменить соединение с базой данных из пользовательского интерфейса. Я использую этот код для быстрой проверки соединения с новыми данными соединения: свойство
public bool CheckAvailable(string sqlServerName, string login, string password)
{
var testConnectionString = GetConnectionString(sqlServerName, login, password);
if (string.IsNullOrWhiteSpace(testConnectionString))
return false;
var result = false;
try
{
var testContext = new EntityContext(testConnectionString);
result = testContext.Database.Exists();
}
catch (Exception ex)
{
log.Error(exception);
}
return result;
}
private string GetConnectionString(string sqlServerName, string login, string password)
{
var sqlConnectionString = new SqlConnectionStringBuilder
{
DataSource = sqlServerName,
InitialCatalog = ConfigurationProvider.DatabaseName,
UserID = login,
Password = password,
MultipleActiveResultSets = true,
ConnectTimeout = 2 // in seconds
};
var efConnectionString = new EntityConnectionStringBuilder
{
Provider = ProviderName,
Metadata = ConnectionMetadata,
ProviderConnectionString = sqlConnectionString.ToString()
};
return efConnectionString.ConnectionString;
}
ConnectTimeout типа SqlConnectionStringBuilder очень важно для быстрой проверки молнии. Если вы знаете, что ваша база данных должна быть доступна и должна быстро реагировать, вы можете установить это значение равным 1 (при установленном локальном сервере SQL проверка занимает 100-200 миллисекунд). Не устанавливайте 0, потому что это означает отсутствие ограничений и их следует избегать в строках соединения.
Я сделал метод расширения для использования с EntityFramework Core.
Вот код:
using Microsoft.EntityFrameworkCore;
using System.Data.Common;
namespace TerminalInventory
{
public static class ExtensionMethods
{
public static bool TestConnection(this DbContext context)
{
DbConnection conn = context.Database.GetDbConnection();
try
{
conn.Open(); // Check the database connection
return true;
}
catch
{
return false;
}
}
}
}
Теперь вам просто нужно позвонить:
if (!context.TestConnection())
{
logger.LogInformation("No database connection. Check the connection string in settings.json. {0}", configuration["connectionString"]);
return;
}