我是lambda表达式的新手,我在试图弄清楚如何在一个表示我的实体框架查询时遇到问题。我也错了,只有更好的方法来做我想要的。如果是这样,请告诉我。我的方案是我有一个高级搜索屏幕,您可以选择搜索名称,客户编号或电话号码。如果需要,您可以搜索超过1个。我使用Entity Framework作为我的后端,并为我的表设置了存储库。以下是我尝试使用的代码
Func<Parties, bool> exp;
exp = null;
if (vm.CustomerNumberCriteria != null)
{
custID = Convert.ToInt32(vm.CustomerNumberCriteria);
exp = o => o.ID == custID;
}
if (vm.NameCriteria != null)
exp += o => o.LastName.Contains(vm.NameCriteria) || o.FirstName.Contains(vm.NameCriteria) || o.MiddleName.Contains(vm.NameCriteria) || o.Designation.Contains(vm.NameCriteria);
if (vm.PhoneNumberCriteria != null)
exp += o => o.CentralPhoneNumbers.Any(child => child.PhoneNumber == vm.PhoneNumberCriteria);
//TODO set tempresults
tempresults = custs.All.Where(exp).ToList();
我的问题是它似乎将此视为一个并且如果在任何搜索条件上存在匹配,我需要结果。
由于
答案 0 :(得分:3)
这里有两个大问题。首先,您使用的是委托,而不是表达式树 - 这意味着您的整个表将被拉回客户端并在那里进行过滤。你想要Expression<Func<Parties, bool>>
。
现在,如果你想建立“或”表达式树,最简单的方法是使用PredicateBuilder
:
var predicate = PredicateBuilder.False<Parties>();
if (vm.CustomerNumberCriteria != null)
{
custID = Convert.ToInt32(vm.CustomerNumberCriteria);
predicate = predicate.Or(o => o.ID == custID);
}
if (vm.NameCriteria != null)
{
custID = Convert.ToInt32(vm.CustomerNumberCriteria);
predicate = predicate.Or(o => o.LastName.Contains(vm.NameCriteria) /* etc */)
}
if (vm.PhoneNumberCriteria != null)
{
predicate = predicate.Or(o => o.CentralPhoneNumbers.Any
(child => child.PhoneNumber == vm.PhoneNumberCriteria));
}
tempresults = custs.All.Where(predicate).ToList();