LINQ / lambda:如何根据另一个表中的信息查询数据库表? (多对多关系)

时间:2017-01-13 09:25:32

标签: c# database linq lambda many-to-many

我有一个包含3个表的数据库方案。一个用于请购单,一个用于医院,一个用于加入两个(多对多关系)。

我想列出数据库中与所选医院相关的所有申请。

这是我到目前为止所做的:

var valgtSykehus = Db.Sykehus.Where(n => n.Navn == sykehus).Single(); //this gives me a variable with my current hospital. I want to list all requistions that contains this.

var Rekvisisjoner = Db.Rekvisisjoner
                    .Where(r => r.Arkivert == true) //get only archived requsitions
                    .Include(p1 => p1.Sykehus) //include hospitals
                    .ToList() //this generates a list of -all- requisitions with the hospitals they are attached to.
                    .Where(x => x.Created > DateTime.Now.AddYears(-3)) /only go 3 years back
                    .Where(x => x.Sykehus.Contains(valgtSykehus)); //here is the problem. I want to discard all requisitions that does NOT contain the hospital in the valgtSykehus variable

无论如何,这给了我零回复,但是如果我跳过最后一行,我会得到所有存档的请求。

3 个答案:

答案 0 :(得分:1)

x.Sykehus.Contains(valgtSykehus)在LINQ to Objects上下文中执行(由于中间ToList调用),并且很可能使用引用相等,这通常应该在您使用跟踪查询时立即生效。

但是,使用带有原始密钥的Any条件,使用单个数据库查询来完成整个事情仍然更安全,也更有效。像这样:

var Rekvisisjoner = Db.Rekvisisjoner
    .Include(r => r.Sykehus) //include hospitals
    .Where(r => r.Arkivert == true) //get only archived requsitions the hospitals they are attached to.
    .Where(r => r.Created > DateTime.Now.AddYears(-3)) /only go 3 years back
    .Where(r => r.Sykehus.Any(s => s.Navn == sykehus));

如果在查询中使用DateTime.Now.AddYears(-3)存在问题,只需将其置于查询之外的变量中并在其中使用。

var minDate = DateTime.Now.AddYears(-3);
var Rekvisisjoner =
   // ...
   .Where(r => r.Created > minDate)
   //...

答案 1 :(得分:0)

问题可能在于Contains的实施。 Contains必须以某种方式检查平等。无论如何,如果你的valgtSykehus对象在逻辑上包含在x.Sykehus中(即具有相同的数据),但不是完全相同的对象(即相同的参考),那么{{1}可能由于引用类型中Contains的默认实现(==为真,如果对象完全相同的引用,则为==,否则无法找到它,即使所有数据是一样的)。

您可以尝试以下方法:

false

如果var Rekvisisjoner = Db.Rekvisisjoner .Where(r => r.Arkivert == true) .Include(p1 => p1.Sykehus) .ToList() .Where(x => x.Created > DateTime.Now.AddYears(-3)) .Where(x => x.Sykehus.Any(sh => sh.Id == valgtSykehus.Id)); (或任何您的ID属性被命名)是值字段(最有可能),只要Id的ID与{{的ID'匹配,这将返回true 1}}。

答案 2 :(得分:0)

哦,我的。 我刚刚意识到,没有任何存档的请购单包含与医院的任何连接,因为当在程序中处理申请时,它们显然是逐一删除的。

我在尝试撤消查询时想到了这一点,所以感谢您的提示。