C# 将EF 6 WPF应用程序转换为EF Core,从工作查询中获取空异常

C# 将EF 6 WPF应用程序转换为EF Core,从工作查询中获取空异常,c#,wpf,entity-framework,entity-framework-core,C#,Wpf,Entity Framework,Entity Framework Core,首先,我可能仍然把自己列为EF的新手。完成了一些代码先行迁移,但只做了一些简单的事情 无论如何,我有一个WPF应用程序,我是使用EF6。我现在正在看.Net Core 3,并决定尝试转换该应用程序 生成我使用的数据库模型 好的,那么问题来了。 在当前运行EF6的应用程序中,此代码运行良好 var items2 = DbContext.UutResult.Where(x => x.StartDateTime != null &&

首先,我可能仍然把自己列为EF的新手。完成了一些代码先行迁移,但只做了一些简单的事情

无论如何,我有一个WPF应用程序,我是使用EF6。我现在正在看.Net Core 3,并决定尝试转换该应用程序

生成我使用的数据库模型

好的,那么问题来了。 在当前运行EF6的应用程序中,此代码运行良好

            var items2 = DbContext.UutResult.Where(x =>
                x.StartDateTime != null && (x.StartDateTime.Value.Date >= startDate &&
                                            x.StartDateTime.Value.Date <= endDate &&
                                            x.StationId == testerId)).Select(x => new TestResultItem()
            {
                TesterId = (int) x.TestSocketIndex,
                TesterType = x.StationId,
                TestDateTime = (DateTime) x.StartDateTime,
                TestResult = x.UutStatus,
                PanelBarcode = x.BatchSerialNumber,
                UutBarcode = x.UutStatus,
                TestTimeSec = (double) x.ExecutionTime,
                TestSteps = x.StepResult.Where(y => y.StepGroup == "Main").Select(y => new TestResultStepItem()
                {
                    StepName = y.StepName,
                    Report = y.ReportText,
                    TestResult = y.Status,
                    UpperLimit = y.StepNumericlimit1.FirstOrDefault().StepNumericlimit2.FirstOrDefault().HighLimit.ToString(),
                    OrderId = (int)y.OrderNumber
                }).ToList()
            }).ToList();
因此y可能有许多子项称为StepNumericlimit1,而这可能有许多子项称为StepNumericlimit2

基本上,我想说的是,如果y有任何StepNumericlimit1孩子,那么就抓住第一个。然后,如果找到一个子项,检查是否有StepNumericlimit2子项。如果是,则从第一个子级获取属性数据

不确定是EF core如何处理这个问题,还是它生成代码的方式,或者甚至是我的查询写得很差。。。或者可能是以上所有的lol

更新:部分EF生成代码,删除无关代码

public partial class StepResult
{
    public StepResult()
    {
        StepNumericlimit1 = new HashSet<StepNumericlimit1>();
    }

    public Guid Id { get; set; }
    public Guid? UutResult { get; set; }
    public virtual UutResult UutResultNavigation { get; set; }
    public virtual ICollection<StepNumericlimit1> StepNumericlimit1 { get; set; }
}

public partial class StepNumericlimit1
{
    public StepNumericlimit1()
    {
        StepNumericlimit2 = new HashSet<StepNumericlimit2>();
    }

    public Guid Id { get; set; }
    public Guid? StepResult { get; set; }
    public double? Data { get; set; }

    public virtual StepResult StepResultNavigation { get; set; }
    public virtual ICollection<StepNumericlimit2> StepNumericlimit2 { get; set; }
}

public partial class StepNumericlimit2
{
    public Guid? PropResult { get; set; }
    public double? HighLimit { get; set; }
    public double? LowLimit { get; set; }

    public virtual StepNumericlimit1 PropResultNavigation { get; set; }
}
关于模型创建

        modelBuilder.Entity<StepNumericlimit1>(entity =>
        {
            entity.ToTable("STEP_NUMERICLIMIT1");

            entity.HasIndex(e => e.StepResult)
                .HasName("StepResultIndex");

            entity.Property(e => e.StepResult).HasColumnName("STEP_RESULT");

            entity.HasOne(d => d.StepResultNavigation)
                .WithMany(p => p.StepNumericlimit1)
                .HasForeignKey(d => d.StepResult)
                .OnDelete(DeleteBehavior.Cascade)
                .HasConstraintName("STEP_NUMERICLIMIT1_STEP_RESULT_FK");
        });

modelBuilder.Entity<StepNumericlimit2>(entity =>
        {
            entity.ToTable("STEP_NUMERICLIMIT2");  

            entity.Property(e => e.HighLimit).HasColumnName("HIGH_LIMIT");

            entity.Property(e => e.LowLimit).HasColumnName("LOW_LIMIT");

            entity.HasOne(d => d.PropResultNavigation)
                .WithMany(p => p.StepNumericlimit2)
                .HasForeignKey(d => d.PropResult)
                .OnDelete(DeleteBehavior.Cascade)
                .HasConstraintName("STEP_NUMERICLIMIT2_STEP_NUMERICLIMIT1_FK");
        });
更新2: 因此,为了提供更多信息,我的目标是创建一个新的项目和数据库,其中包含虚拟数据,但非常简单,即剥离不需要的表和与查询无关的列

我这样做了,现在查询工作正常,即使子属性为空。我已经在两个项目中检查了scafolding生成的代码,它们是相同的


那么我如何才能找到问题所在呢?

这个解决方案应该可以正常工作

var items2 = DbContext.UutResult.Include(r=>r.StepNumericlimit1).ThenInclude(r=>r.StepNumericlimit2).Where(x =>
                x.StartDateTime != null && (x.StartDateTime.Value.Date >= startDate &&
                                            x.StartDateTime.Value.Date <= endDate &&
                                            x.StationId == testerId)).Select(x => new TestResultItem()
            {
                TesterId = (int) x.TestSocketIndex,
                TesterType = x.StationId,
                TestDateTime = (DateTime) x.StartDateTime,
                TestResult = x.UutStatus,
                PanelBarcode = x.BatchSerialNumber,
                UutBarcode = x.UutStatus,
                TestTimeSec = (double) x.ExecutionTime,
                TestSteps = x.StepResult.Where(y => y.StepGroup == "Main").Select(y => new TestResultStepItem()
                {
                    StepName = y.StepName,
                    Report = y.ReportText,
                    TestResult = y.Status,
                    UpperLimit = y.StepNumericlimit1.FirstOrDefault().StepNumericlimit2.FirstOrDefault().HighLimit.ToString(),
                    OrderId = (int)y.OrderNumber
                }).ToList()
            }).ToList();
有关更多信息,请阅读本文档

检查您的连接字符串,可能是因为它没有定义或不正确,此外,请查看其中一些答案,看看是否有人可以帮助=>我知道它不是字符串,因为我可以很好地运行其他不太复杂的查询。另外,如果我注释掉我确定为问题的那一行,它也可以正常运行。编辑后,查看url,检查对象y及其ReferenceProperties是否为NULL。在Ef core中,您需要使用Include函数在函数DbContext.UutResult.Include之前检索相关数据子项。。。EF 6中有一个错误,EF Core似乎不起作用。我接受了你的查询,修改了顶行,改为这一行。DbContext.UutResult.Includex=>x.StepResult.ThenIncludex=>x.StepNumericlimit1.ThenIncludex=>x.StepNumericlimit2.Where但仍然存在错误。您能给我数据库架构吗?这是一个业务数据库,所以我只能提供什么。我需要查看相关表之间的关系,以便能够解决此问题。我将添加一些EF生成的代码,去掉无Estentiall属性。
var items2 = DbContext.UutResult.Include(r=>r.StepNumericlimit1).ThenInclude(r=>r.StepNumericlimit2).Where(x =>
                x.StartDateTime != null && (x.StartDateTime.Value.Date >= startDate &&
                                            x.StartDateTime.Value.Date <= endDate &&
                                            x.StationId == testerId)).Select(x => new TestResultItem()
            {
                TesterId = (int) x.TestSocketIndex,
                TesterType = x.StationId,
                TestDateTime = (DateTime) x.StartDateTime,
                TestResult = x.UutStatus,
                PanelBarcode = x.BatchSerialNumber,
                UutBarcode = x.UutStatus,
                TestTimeSec = (double) x.ExecutionTime,
                TestSteps = x.StepResult.Where(y => y.StepGroup == "Main").Select(y => new TestResultStepItem()
                {
                    StepName = y.StepName,
                    Report = y.ReportText,
                    TestResult = y.Status,
                    UpperLimit = y.StepNumericlimit1.FirstOrDefault().StepNumericlimit2.FirstOrDefault().HighLimit.ToString(),
                    OrderId = (int)y.OrderNumber
                }).ToList()
            }).ToList();