C#:测试实体框架 FromSql 以确保正确的语法

3 c# sqlite entity-framework entity-framework-core

我正在编写FromSql使用 InMemory 数据库测试 语句。我们正在尝试使用 Sqlite。

运行下面的Sql通过单元测试没有报错。

select * from dbo.Product
Run Code Online (Sandbox Code Playgroud)

但是,这样做也会通过不正确的 sql 语法。想要使用不正确的 sql 语法使测试失败。我们如何正确测试 FromSql?

没有错误来自错误的语法。

seledg24g5ct * frofhm dbo.Product
Run Code Online (Sandbox Code Playgroud)

完整代码:

namespace Tests.Services
{
    public class ProductTest
    {
        private const string InMemoryConnectionString = "DataSource=:memory:";
        private SqliteConnection _connection;
        protected TestContext testContext;

        public ProductServiceTest()
        {
            _connection = new SqliteConnection(InMemoryConnectionString);
            _connection.Open();
            var options = new DbContextOptionsBuilder<TestContext>()
                    .UseSqlite(_connection)
                    .Options;
            testContext= new TestContext(options);
            testContext.Database.EnsureCreated();
        }


        [Fact]
        public async Task GetProductByIdShouldReturnResult()
        {
            var productList = testContext.Product
    .FromSql($"seledg24g5ct * frofhm dbo.Product");

            Assert.Equal(1, 1);
        }
Run Code Online (Sandbox Code Playgroud)

使用网络核心 3.1

Iva*_*oev 5

这里有两件事需要考虑。

首先,FromSql方法只是在 EF Core 中使用原始 SQL 查询的一个小桥梁。除了查找参数占位符并将 db 参数与它们相关联之外,调用该方法时不会对传递的 SQL 字符串进行任何验证/解析。为了得到验证,它必须被执行

其次,为了支持对FromSql结果集的查询组合,该方法返回IQueryable<T>. 这意味着它不会立即执行,而是仅当/当结果被枚举时才执行。这可能发生,当您使用foreach循环遍历它,或者调用方法一样ToListToArray或EF核心特定Load扩展方法,这是类似ToList的,但不创建列表-相当于foreach环W / O体,如

foreach (var _ in query) { }
Run Code Online (Sandbox Code Playgroud)

话虽如此,代码片段

var productList = testContext.Product
    .FromSql($"seledg24g5ct * frofhm dbo.Product");
Run Code Online (Sandbox Code Playgroud)

基本上什么都不做,因此不会为无效的 SQL 产生异常。您必须使用上述方法之一执行它,例如

productList.Load();
Run Code Online (Sandbox Code Playgroud)

或者

var productList = testContext.Product
    .FromSql($"seledg24g5ct * frofhm dbo.Product")
    .ToList();
Run Code Online (Sandbox Code Playgroud)

并断言预期的异常。

有关详细信息,请参阅EF Core 文档的原始 SQL 查询查询工作原理部分。