使用EF Core 2.1检查表是否存在

安德烈·费乔

在实体框架中,可以通过以下方式检查表的存在:

bool exists = context.Database
                 .SqlQuery<int?>(@"
                     SELECT 1 FROM sys.tables AS T
                     INNER JOIN sys.schemas AS S ON T.schema_id = S.schema_id
                     WHERE S.Name = 'SchemaName' AND T.Name = 'TableName'")
                 .SingleOrDefault() != null;

我正在使用EF Core 2.1,但该方法SqlQuery不存在。

检查表是否存在的正确方法是什么?理想情况下,无需尝试访问该表并假设如果引发异常则该表不存在。

编辑:我的最终实现

public bool TableExists(string tableName)
{
    return TableExists("dbo", tableName);
}

public bool TableExists(string schema, string tableName)
{
    var connection = Context.Database.GetDbConnection();

    if (connection.State.Equals(ConnectionState.Closed))
        connection.Open();

    using (var command = connection.CreateCommand())
    {
        command.CommandText = @"
            SELECT 1 FROM INFORMATION_SCHEMA.TABLES 
            WHERE TABLE_SCHEMA = @Schema
            AND TABLE_NAME = @TableName";

        var schemaParam = command.CreateParameter();
        schemaParam.ParameterName = "@Schema";
        schemaParam.Value = schema;
        command.Parameters.Add(schemaParam);

        var tableNameParam = command.CreateParameter();
        tableNameParam.ParameterName = "@TableName";
        tableNameParam.Value = tableName;
        command.Parameters.Add(tableNameParam);

        return command.ExecuteScalar() != null;
    }
}
加布里埃尔·卢西(Gabriel Luci)

ExecuteSqlCommand

context.Database.ExecuteSqlCommand("...")

但是,仅限于返回一个整数,该整数指示受影响的行数。如果您正在执行SELECT则任何行都不会受到影响,因此它对于您想要的内容实际上并不起作用。

还有FromSql,但仅适用于表,不适用于数据库级别:

context.TableName.FromSql("SELECT ...")

对于您正在做的事情,更好的选择是DbConnection从EF获取并创建自己的DbCommand这将返回您期望的结果:

var conn = context.Database.GetDbConnection();
if (conn.State.Equals(ConnectionState.Closed)) await conn.OpenAsync();
using (var command = conn.CreateCommand()) {
    command.CommandText = @"
    SELECT 1 FROM sys.tables AS T
        INNER JOIN sys.schemas AS S ON T.schema_id = S.schema_id
    WHERE S.Name = 'SchemaName' AND T.Name = 'TableName'";
    var exists = await command.ExecuteScalarAsync() != null;
}

这里提醒一句:不要把DbConnection你从GetDbConnection()一个using声明,或关闭它,当你完成。该连接用于该DbContext实例的生命周期因此,如果关闭它,EF以后发出的任何请求都将失败。它也可能已经在您的代码之前打开了,这就是为什么我在其中进行测试以查看它是否在调用之前关闭的原因OpenAsync()

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章