测试Entity Framework是否与某些东西相关联

时间:2011-02-22 15:46:37

标签: .net entity-framework

创建新的EntityCollection对象时,在尝试对该集合执行某些操作之前,连接不会尝试打开数据库。我需要确定实体集合是否具有有效连接,我找不到有效的方法。

目前我的代码中已经有了这个:

var db = new MyEntityCollection();

try
{
     var checkworking = from c in db.Customers select c;
}
catch 
{ 
     ConnectToBackUp();
}

这不仅是可怕的代码,而且非常慢,因为它等待一个年龄来确​​定连接是否在激活之前是否有效。

我知道我可以通过使用ConnectionTimeout来控制放弃之前等待的时间,但这只是另一个丑恶的黑客行为,会让情况变得更糟。

当然有更好的方法吗?

6 个答案:

答案 0 :(得分:31)

最简单的:

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;
        }
    }
}

答案 1 :(得分:11)

您是否只想查看数据库连接是否有效。如果是这样,请查看objectcontext.databaseExists()

答案 2 :(得分:8)

通过绕过房屋并构建一个新的连接字符串以使用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;
            }
        }
    }

答案 3 :(得分:1)

网络或数据库服务器层不应提供此类基础设施吗?手动处理与备份服务器的连接看起来很奇怪。此外,无法等待超时,因为您必须首先尝试打开与主服务器的连接。

ObjectContext.Connection可以访问连接本身。此属性应返回EntityConnection实例,该实例包含与真实数据库保持连接的StoreConnection属性。您可以检查此连接的状态。

答案 4 :(得分:0)

在我的应用中,用户可以从UI更改与数据库的连接。我使用此代码快速检查与新连接数据的连接:

    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;
    }
SqlConnectionStringBuilder 类型的

ConnectTimeout 属性对于快速执行检查闪电非常重要。如果您知道,您的数据库应该可用且应该快速响应,则可以将此值设置为1(在本地安装SQL Server需要100-200毫秒才能检查)。不要设置0,因为它表示没有限制,应该在连接字符串中避免使用。

答案 5 :(得分:0)

我使用了https://www.dartlang.org/install/archive与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;
}