c# - 有没有办法直接查询 Entity Framework Core 使用的内存数据库?

标签 c# .net database entity-framework-core

我正在使用内存数据库提供程序对 .Net Core 2.2 应用程序进行一些测试。我需要使应用程序中的表之一无法访问 - 通过重命名或删除它。有没有办法直接对内存数据库运行这种查询?我尝试使用以下方法建立连接:

context.Database.GetDbConnection();

但这会引发错误

Relational-specific methods can only be used when the context is using a relational database provider.



我知道我可以使用以下方法销毁整个数据库:
context.Database.EnsureDeleted();

但我需要保留它,只销毁或重命名一张表。

最佳答案

InMemory provider 不受关系数据库的支持,并且有一组不同的操作不支持您的情况。

您可以改为使用 SQLite 内存模式 ( doc ),然后创建一个拦截器来拦截发出的 EF 命令,并抑制表的创建,或抑制针对该表的其他查询。

public class MyInterceptor : DbCommandInterceptor {
    public override InterceptionResult<int> NonQueryExecuting(DbCommand command, CommandEventData eventData, InterceptionResult<int> result) {
        if (ContainsBannedTable(command)) {
            //suppress the operation
            result = InterceptionResult<int>.SuppressWithResult(0);
        }
        return base.NonQueryExecuting(command, eventData, result);
    }

    private bool ContainsBannedTable(DbCommand command) {
        //or custom logic
        return command.CommandText.Contains("ToDeleteEntity");
    }
}

尝试访问不需要的表时,以下内容将引发异常( Microsoft.EntityFrameworkCore.DbUpdateException... SqliteException: SQLite Error 1: 'no such table: ToDeleteEntity' )。

var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
var options = new DbContextOptionsBuilder<MyContext>()
                  .UseSqlite(connection)
                  .AddInterceptors(new MyInterceptor())
                  .Options
                  ;

var context = new MyContext(options);
context.Database.EnsureCreated();

context.AllowedEntity.Add(new AllowedEntity { Id = 1 });
context.SaveChanges();
Console.WriteLine(context.AllowedEntity.FirstOrDefault()?.Id); //1 - ok

context.ToDeleteEntity.Add(new ToDeleteEntity { Id = 1 });
//will throw an exception
context.SaveChanges();
Console.WriteLine(context.ToDeleteEntity.FirstOrDefault()?.Id);

//close the connection and clean up
//...

public class MyContext : DbContext {
    public MyContext(DbContextOptions options) : base(options) {
    }

    public DbSet<AllowedEntity> AllowedEntity { get; set; }
    public DbSet<ToDeleteEntity> ToDeleteEntity { get; set; }
}

public class ToDeleteEntity {
    public int Id { get; set; }
}

public class AllowedEntity {
    public int Id { get; set; }
}

关于c# - 有没有办法直接查询 Entity Framework Core 使用的内存数据库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59773502/

相关文章:

c# - 如何避免字符串在命令行中的每个空格处拆分

c# - 关于方法锁定的最佳实践

c# - 警告 CS8032 无法加载文件或程序集 'Microsoft.CodeAnalysis,版本 = 3.3.0.0

.net - SSD 驱动器上奇怪的目录删除行为

c# - Web 客户端 - 在此上下文中不允许异步操作

ruby-on-rails - 建模收藏夹

c# - 日期时间编码

.net - System.DirectoryServices.AccountManagement 性能问题?

php - 使用 PostgreSQL 或 Mysql 的 SQL 查询进度

mysql - 如何使用 Ruby 将数据库从 Sqlite3 转换为架构不一致的 Mysql