Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C LINQ-从查询结果中排除空对象[EF-无引用Int]_C#_Sql_Entity Framework_Linq_Lazy Loading - Fatal编程技术网

C# C LINQ-从查询结果中排除空对象[EF-无引用Int]

C# C LINQ-从查询结果中排除空对象[EF-无引用Int],c#,sql,entity-framework,linq,lazy-loading,C#,Sql,Entity Framework,Linq,Lazy Loading,本质上,我试图从查询结果中排除具有空子对象的实体。我希望以最有效的方式完成这项工作,加载所需的最小数据量 我正在使用一个不强制引用完整性的数据库;一些学生已被删除,因此,不幸的是,一些确实指定了PupilID的报告不再有匹配的学生。我想排除这类报道 下面是我最初的问题解决方法,但这里是我的核心问题 var test1 = DbContext.Report .Where(x => x.Pupil != null).ToList(); var test2 =

本质上,我试图从查询结果中排除具有空子对象的实体。我希望以最有效的方式完成这项工作,加载所需的最小数据量

我正在使用一个不强制引用完整性的数据库;一些学生已被删除,因此,不幸的是,一些确实指定了PupilID的报告不再有匹配的学生。我想排除这类报道

下面是我最初的问题解决方法,但这里是我的核心问题

var test1 =
    DbContext.Report
        .Where(x => x.Pupil != null).ToList();

var test2 =
    DbContext.Report
        .Include(x => x.Pupil)
        .Where(x => x.Pupil != null).ToList();

if (test1.Count(x => x.Pupil == null) > 0)
{
    var bp = "hit"; // I know this doesn't work
}

if (test2.Count(x => x.Pupil == null) > 0)
{
    var bp = "hit"; // But why doesn't this? And how can I make it work...
}

if (test1.Where(x => x.Pupil != null).Count(x => x.Pupil == null) > 0)
{
    var bp = "not hit"; // Without having to do this
}
我假设EF延迟加载有一些问题,但我已经尝试显式加载并包含它们,但没有效果;唯一有效的方法是对整个查询调用.ToList,它将评估代理并允许我正确地排除它们,然而,要做到这一点,它将加载数据,我不需要将其丢弃。这有什么办法吗

原始问题方法:

public IEnumerable<Report> GetCurrentReportsForStaffByUsername(string username)
{
    var staffId =
        GetStaffIdFromUsername(username);

    var query = (
        from reports in this.DbContext.Reports.Include(x => x.Pupil).Where(x => x.Pupil != null)
       where reports.StaffId == staffId
          && reports.Pupil != null
      select reports)
            .Include(r => r.Pupil)
            .Where(r => r.Pupil != null);

    if (query.Any(q => q.Pupil == null))
    {
        var error = "how?!?!?!?!?!?!?!?"; // <-- Hits this
    }

    if (query.ToList().Any(q => q.Pupil == null))
    {
        var error = "really?";
    }

    return query;
}

感谢您抽出时间:

不是最好看的代码,但它做了它应该做的

var test2 =
    DbContext.Report
        .Where(r => DbContext.Pupils.Any(p => p.PupilId == r.PupilId)).ToList();
或者在linq到sql中

public IEnumerable<Report> GetCurrentReportsForStaffByUsername(string username)
{
    var staffId =
        GetStaffIdFromUsername(username);

    var query = (
        from reports in this.DbContext.Reports
       where reports.StaffId == staffId
          && this.DbContext.Pupils.Any(p => p.PupilID == reports.PupilID) // <- this
      select reports)

    return query;
}

通常你会这样做:以你的例子为基础

public IEnumerable<Report> GetCurrentReportsForStaffByUsername(string username)
{
    var staffId =
        GetStaffIdFromUsername(username);

    var query = (
        from reports in this.DbContext.Reports
        join pupil in this.DbContext.Pupils on reports.PupilID equals pupil.PupilID
        where reports.StaffId == staffId
        select reports)

    return query;
}
这似乎是你想要的。 我还建议使用一个类似的工具来尝试这些东西,因为您可以编写c代码,并且它有一个选项卡来显示SQL中的结果,虽然它并不总是1对1,但它给了您一个想法


这样,您可以尝试不同的方法,大致了解结果

如果你能解释一下如何使用@BugFinder,那就太好了。我看不出在这种情况下如何使用它;我不想替换null对象,我想从查询结果中完全排除它的父对象。干杯,defaultifempty允许您的linq正常工作,您可以排除丢失的linqvalues@BugFinder我根本看不到,请您发布示例实现。即使只是添加了我的代码的一个复制版本,我也不介意在理解它后立即填充您的答案,但这条评论真的没有帮助,我不喜欢没有解释的关闭请求。@MatthewHudson看起来您正在使用include作为连接,然后稍后检查是否有任何报告的瞳孔为空,它已经做到了。也许可以尝试在报告中加入p。PupilId等于p。PupilId您可以保留第一份报告。Includex=>x。不需要其他报告。
SELECT * FROM Report r
INNER JOIN Pupil p ON r.PupilID = p.PupilID