我有一个简单连接到几个表的链接查询,以及一个where子句,由于某些奇怪的原因,查询似乎没有遵守where子句。
我的查询如下:
from p in Platforms
join c in Compartments on p.Id equals c.PlatformId
join ci in CompartmentItems on c.Id equals ci.CompartmentId
where p.Id == 4042 && !ci.Archived && !c.Archived
select c
一个简单的linqpad screnshot显示CompartmentItems
被附加到Compartments
,但不管它们是否存档。
感觉我在这里很密集,任何人都可以帮我识别查询问题吗?
任何想法都非常感激。
编辑: 所以我回过头来仔细研究了这一点,并确定了为什么我只退回隔间。这是由于存储库通常只返回要消费的域类型。 因此,在不引入单个随机DTO类型对象的情况下,我不能返回多个实体类型(其他repos都不会返回除域类型之外的任何内容)。
因此,我有4个选择:
有关最佳方法的任何想法吗?
答案 0 :(得分:5)
你正在拿走你的隔间,将其与隔间物品连接,过滤掉一些隔间物品,然后忽略你加入桌子的所有隔间物品完全只选择隔间,然后使用完全不同的机制来获取每个隔离专区的所有隔离专区项目,即使用内置关系属性。
要仅获取与您的指定过滤器匹配的隔离专区项目,您需要实际选择使用select
子句过滤的隔离专区项目,然后不使用Include
包括所有。这可能类似于:
from p in Platforms
join c in Compartments on p.Id equals c.PlatformId
join ci in CompartmentItems.Where(ci => !ci.Archived)
on c.Id equals ci.CompartmentId into compItems
where p.Id == 4042 && !c.Archived
select new
{
Compartment = c,
CompartmentItems = compItems,
}
答案 1 :(得分:1)
查看SQL查询本身。我确信它服从你的过滤器。我打赌你有懒加载,这就是你看到所有CompartmentItems的原因。
或者,如果您不使用SQL后端,则必须在Compartment和CompartmentItems之间建立关系。当您使用导航属性时,它将返回所有隔离专区。
这里没有错误。
尝试使用所有CompartmentItems.Archived = 1创建一个隔间。您将看到您的声明不会返回此隔间。
答案 2 :(得分:0)
尝试这样做。
from p in Platforms
join c in Compartments on p.Id equals c.PlatformId
join ci in CompartmentItems on c.Id equals ci.CompartmentId
where p.Id == 4042
where !ci.Archived
where !c.Archived
select c
它可以解决链接尝试查询属性的相同记录的问题。当逻辑由&&和它似乎被读取到机器
p.Id == 4042 && !p.Archived && !p.Archived
这是LINQ仅使用列表中的第一项应用属性过滤器的结果,而不管剩余项目的差异。
答案 3 :(得分:0)
Linq加入into子句和where condition
var li = (from cert in db.tbl_ISOCetificate
join comCert in db.tbl_ComGroupCertificate.Where(x=>x.GroupID ==GroupID) on cert.Cert_id equals comCert.CerID into jo
from b in jo.DefaultIfEmpty()
select new { cert.Cert_id, cert.Cert_Name}).ToList();