You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用linq2db的Lead函数时抛出NullReferenceException异常求助

环境

我们使用以下技术栈:

  • .NET Core 3.1
  • Microsoft.EntityFrameworkCore 3.1.9
  • Npgsql 4.1.9
  • LinqKit.Microsoft.EntityFrameworkCore 3.2.3
  • linq2db.EntityFrameworkCore 3.7.0
实体类定义

我们有两个通过Scaffold生成的实体类:

[Table("testrunconfig", Schema = "fit")]
public partial class Testrunconfig
{
    public Testrunconfig()
    {
        Testruntestgrp = new HashSet<Testruntestgrp>();
    }
    
    [Key]
    [Column("id")]
    public int Id { get; set; }
    
    [InverseProperty("Testrunconfig")]
    public virtual ICollection<Testruntestgrp> Testruntestgrp { get; set; }
}

[Table("testruntestgrp", Schema = "fit")]
public partial class Testruntestgrp
{
    [Key]
    [Column("id")]
    public int Id { get; set; }
    
    [Column("testname")]
    public string Testname { get; set; }
    
    [Column("status")]
    public string Status { get; set; }

    [ForeignKey(nameof(TestrunconfigId))]
    [InverseProperty("Testruntestgrp")]
    public virtual Testrunconfig Testrunconfig { get; set; }
}
linq2db日志配置

我们通过以下代码启用linq2db的控制台日志:

private void ConfigureLinq2DbConsoleLogging()
{
    DataConnection.TurnTraceSwitchOn();
    DataConnection.WriteTraceLine = (string s1, string s2, TraceLevel _) => Debug.WriteLine($"{s1}: {s2}");
}
查询需求与实现

我们需要编写一个同时用到LinqKit(调用DetermineFinalResultForTestFunc表达式)和linq2db(使用SQL窗口函数LEAD)的查询,目的是:通过Sql.Ext.Lead所在的Where条件,保留每个FinalResultSelectedTest值连续相同序列中的最后一条数据。

相关代码如下:

private readonly static Expression<Func<Testrunconfig, string, string>> DetermineFinalResultForTestFunc =
    (Testrunconfig trc, string testName) =>
        trc == null ?
            null :
            (trc.Finished == null ?
                "IN_PROGRESS" :
                (trc.Testruntestgrp == null || trc.Testruntestgrp.Any(x => x.Testname == testName && x.Status != "OK") ?
                    "ERROR" :
                    "OK")
                );

public void GetTestBisectedExecutions(string testName)
{
    var result = _fitDbContext.Testrunconfig
        .AsExpandable()
        .Include(x => x.Testruntestgrp)
        .Where(x => x.Testruntestgrp.Any(y => y.Testname == testName))
        .OrderByDescending(x => x.Id)
        .Select(x => new TestExecutionHelper()
        {
            TestrunConfig = x,
            SelectedTestName = testName,
            FinalResultSelectedTest = DetermineFinalResultForTestFunc.Invoke(x, testName)
        })
        .Where(x => Sql.Ext.Lead(x.FinalResultSelectedTest, Sql.Nulls.Respect)
            .Over()
            .OrderByDesc(x.TestrunConfig.Id)
            .ToValue() != x.FinalResultSelectedTest
        )
        .ToLinqToDB()
        .ToList();
}
预期效果

应用Lead所在的Where条件前的数据:

TestrunConfig.IdFinalResultSelectedTest
7WARNING
6OK
5OK
4ERROR
3ERROR
2OK
1OK

应用条件后的数据:

TestrunConfig.IdFinalResultSelectedTest
7WARNING
5OK
3ERROR
1OK
异常信息

执行上述查询时抛出以下异常,移除Lead所在的Where条件则无异常:

Exception thrown: 'System.NullReferenceException' in linq2db.dll
Object reference not set to an instance of an object.

The thread 0xad6c has exited with code 0 (0x0).
The thread 0x5244 has exited with code 0 (0x0).
Exception thrown: 'System.Reflection.TargetInvocationException' in System.Private.CoreLib.dll
To generate test code to diagnose the problem set 'LinqToDB.Common.Configuration.Linq.GenerateExpressionTest = true'.: DataConnection
...
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request finished in 19635.7644ms 500 text/html; charset=utf-8
更新后的尝试

按照建议修改查询后,代码如下:

var result = _fitDbContext.Testrunconfig
    //.Include(x => x.Testruntestgrp)
    .Where(x => x.Testruntestgrp.Any(y => y.Testname == testName))
    .OrderByDescending(x => x.Id)
    .Select(x => new TestExecutionHelper()
    {
        TestrunConfig = x,
        SelectedTestName = testName,
        FinalResultSelectedTest = DetermineFinalResultForTestFunc.Compile()(x, testName)
    })
    .Select(x => new
    {
        Helper = x,
        NextVal = Sql.Ext.Lead(x.FinalResultSelectedTest, Sql.Nulls.Respect)
            .Over()
            .OrderByDesc(x.TestrunConfig.Id)
            .ToValue()
    })
    .Where(x => x.NextVal != x.Helper.FinalResultSelectedTest)
    .Select(x => x.Helper)
    .ToLinqToDB()
    .ToList();

但仍抛出相同异常:

Exception thrown: 'System.NullReferenceException' in linq2db.dll
Object reference not set to an instance of an object.

Exception thrown: 'System.Reflection.TargetInvocationException' in System.Private.CoreLib.dll
To generate test code to diagnose the problem set 'LinqToDB.Common.Configuration.Linq.GenerateExpressionTest = true'.: DataConnection
...
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request finished in 15984.5845ms 500 text/html; charset=utf-8

现寻求解决该NullReferenceException异常的技术方案。


内容的提问来源于stack exchange,提问作者Aleks Vujic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 12:32:19