And*_*ijo 1 c# entity-framework entity-framework-core
在Entity Framework中,可以通过以下方式检查表的存在:
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;
Run Code Online (Sandbox Code Playgroud)
我使用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;
}
}
Run Code Online (Sandbox Code Playgroud)
context.Database.ExecuteSqlCommand("...")
Run Code Online (Sandbox Code Playgroud)
但是,它仅限于返回一个整数,表示受影响的行数.如果您正在进行操作SELECT,则不会影响任何行,因此它并不能真正满足您的需求.
还有FromSql,但这只适用于表,而不适用于数据库级别:
context.TableName.FromSql("SELECT ...")
Run Code Online (Sandbox Code Playgroud)
对于你正在做的事情,一个更好的选择是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;
}
Run Code Online (Sandbox Code Playgroud)
这里提醒一句:千万不要把DbConnection你从GetDbConnection()一个using声明,或关闭它,当你完成.该连接用于该DbContext实例的生命周期.因此,如果您关闭它,EF发出的任何后续请求都将失败.它也可能已经在你的代码之前打开了,这就是为什么我在那里放一个测试,看它是否在调用之前关闭了OpenAsync().
| 归档时间: |
|
| 查看次数: |
1371 次 |
| 最近记录: |