在我的Customer
模型中,我已经
public virtual ICollection<AddressModel> AddressIDs { get; set; }
其中引用了AddressModel
,这给了我客户与他们的地址之间的一对多关系。
我有一个使用的搜索功能
var CustomerList = _context.Customers
.Where(ps => ps.Surname.Contains(surnameToSearchFor))
按姓氏限制返回的数据集。
我正在尝试添加在地址中搜索邮政编码的功能。通过各种链接,它可以在Visual Studio中运行,但在执行时会中断
CustomerList = CustomerList
.Include(ps => ps.AddressIDs
.Where(a => a.Postcode == postcodeToSearchFor));
有错误
InvalidOperationException: The property expression 'ps => {from AddressModel a in ps.AddressIDs where ([a].Postcode == __p_0) select [a]}' is not valid. The expression should represent a property access: 't => t.MyProperty
如何在子表上的LINQ中添加Where
子句?
修改 对于建议使用Multiple WHERE clause in Linq作为答案的人,该问题显然与单个表有关,而我明确询问了子表。
答案 0 :(得分:5)
您不能在“包含”中使用where语句。您可以通过单个linq查询获得所需的内容,如下所示:
select candidateID,Salary,rank from candidateSalary where candidateID = 2
+---------------+-----------+------+
| candidateID | Salary | rank |
+---------------------------+------+
| 2 | 12000 | 1 |
+---------------------------+------+
答案 1 :(得分:2)
正如已经提到的另一个答案(由Progressive提出)一样,您无法根据Include
进行过滤。
(渐进式的)另一个答案可能是 为您解决,或者可能不是。它会给您邮政编码中至少有一个地址的所有客户,但随后它将加载该客户的所有地址(包括邮政编码不同的地址)。< / p>
如果您仅希望检索邮政编码的地址(我怀疑是这种情况),则会写出此答案。如果您只希望检索客户并且仅过滤其地址(而不加载地址),则另一个解决方案(通过Progressive)是解决方案。
正如我所说,您不能通过包含来做到这一点。但是,还有其他解决方案:
1。查找地址并包括客户。
而不是查找客户并包括他们的地址。
var addresses = _context.Addresses
.Include(a => a.Customer)
.Where(a =>
a.Postcode == postcodeToSearchFor
&&
a.Customer.Surname.Contains(surnameToSearchFor))
.ToList();
您仍然可以通过这种方式获得客户列表:
var customer = addresses.Select(a => a.Customer).Distinct();
作为一般的经验法则,请始终从孩子处开始查询并包括其父母,而不是相反。在某些情况下并不重要,但是在您的特定情况下,这很重要,因为您要避免隐式加载 all 个子级。
2。明确定义结果集
换句话说,使用Select()
。
这可以让您更好地控制结果,以防万一您对结果确实有特定的期望,但是它比较冗长,而且(imo)不如其他解决方案好。仅在第一种解决方案不适合您时才使用它。
_context.Customers.Where(ps =>
ps.Surname.Contains(surnameToSearchFor)
&&
ps.AddressIDs.Any(ad => ad.Postcode == postcodeToSearchFor))
.Select(ps => new
{
Customer = ps,
Addresses = ps.AddressIDs.Where(ad => ad.Postcode == postcodeToSearchFor))
})
.ToList();
请注意,此处不需要Include()
。 Include()
配置隐式加载行为,但是您的Select()
显式加载数据。
答案 2 :(得分:1)
尝试一下:
var CustomerList = _context.Customers.Where(ps => ps.Surname.Contains("surnameToSearchFor")).Select(ps => new
{
Surname = ps.Name,
AddressIDs = ps.AddressIDs.Where(a => a.PostCode == postcodeToSearchFor)
});
答案 3 :(得分:0)
我需要具有特定地址的Customer
模型的姓氏和姓氏,因此根据Progressive的回答,我使用了此姓氏
var CustomerList = CustomerList.Where(ps => ps.AddressIDs
.Any(a => a.Postcode.Contains(postcodeToSearchFor)));
这会带回邮政编码的任何部分的任何Customer
,但不会带回具有空白或null
邮政编码的任何人。