Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用EF Core 2.1检查表是否存在_C#_Entity Framework_Entity Framework Core - Fatal编程技术网

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

C# 使用EF Core 2.1检查表是否存在,c#,entity-framework,entity-framework-core,C#,Entity Framework,Entity Framework Core,在实体框架中,可以通过以下方式检查表的存在: 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 WHER

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

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;

但是,它仅限于返回一个整数,指示有多少行受到影响。如果您正在执行
选择
,则不会影响任何行,因此它实际上无法满足您的需要

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

context.TableName.FromSql("SELECT ...")
对于您正在做的事情,更好的选择是从EF获取
DbConnection
,并创建您自己的
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;
}

这里有一句警告:不要将从
GetDbConnection()
获得的
DbConnection
放在
using
语句中,或者在完成后将其关闭。该连接用于该
DbContext
实例的生命周期。因此,如果您关闭它,EF以后发出的任何请求都将失败。也有可能它在您的代码之前就已经打开了,这就是为什么我在调用
OpenAsync()

之前在那里放了一个测试,看看它是否关闭了。您可以展开吗
是无效的
?您是否尝试过
FromSql
?通常的问题是关于“开放查询”的,还是严格的表存在性检查?@JohnB该方法在EF Core中不存在。如何使用FromSql检查表是否存在?据我所知,它需要映射到一个实体,那么我是否需要为信息架构构建一个Dto?您需要知道要从SQL使用的表,因此我认为您无法使用它来确定表是否存在。现在我回到办公室,我可以做一些测试。我找到了另一种方法。我已经更新了我的答案。谢谢Gabriel,我还用我的最终实现编辑了我的问题。Nit:关闭连接是可以的(它将被重新打开),处理连接(按照使用)不是,因为以后打开的调用将失败。。事实上,确保连接已关闭可能“更好”的做法是立即将连接返回池。
context.TableName.FromSql("SELECT ...")
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;
}