List<Guid> toBeFilteredCarIds = new List<Guid>();
toBeFilteredCarIds.Add(new Guid("4cc70c3a-405c-4a5c-b2cd-0429a5bc06ef"));
var cars = ef.Cars
.Include("CarProfile.Option.OptionType")
.Where(c => c.CarStatusId == 1);
cars.Join(ef.CarProfile,
t1 => t1.CarId,
t2 => t2.Car.CarId,
(t1, t2) => new { t1, t2 }).Where(o => o.t2.IsActive == true).Select(o => o.t1);
var filteredCars = cars.ToList().Where(u => toBeFilteredCarIds.Contains(u.CarId));
上面的代码试图获取CarProfile处于活动状态的Car列表,并且CarId在toBeFilteredCarId列表中。
然而,正如您在最后一行中所看到的,我首先执行.ToList((,然后执行Where子句以通过CarId进行筛选。
这显然将首先从DB中获取所有汽车,然后进行过滤。这是非常昂贵的。
我已经尝试了其他人对其他答案的建议:
List<Guid> toBeFilteredCarIds = new List<Guid>();
toBeFilteredCarIds.Add(new Guid("4cc70c3a-405c-4a5c-b2cd-0429a5bc06ef"));
var cars = ef.Cars
.Include("CarProfile.Option.OptionType")
.Where(c => toBeFilteredCarIds.Contains(c.CarId) && c.CarStatusId == 1);
cars.Join(ef.CarProfile,
t1 => t1.CarId,
t2 => t2.Car.CarId,
(t1, t2) => new { t1, t2 }).Where(o => o.t2.IsActive == true).Select(o => o.t1);
var filteredCars = cars.ToList();
但这对我不起作用,它给了我这个错误:
LINQ to Entities无法识别方法"Boolean Contains(System.Guid("方法,并且此方法无法转换为存储表达式
我可以在stackoverflow上看到,许多人已经标记为回答了上述方法:
.Where(c => toBeFilteredCarIds.Contains(c.CarId)
但对我不起作用。
顺便说一下,我使用了:VS2008、EF 3.5,并且我已经使用了System.Data.Entity在我的使用语句中。
上面使用的"Include"很重要,因为我需要把一切都准备好,因为后面会有大量的循环读取数据
IEnumerable
上的Contains
直到4.0才添加,因此如果您在3.5中遇到问题,则需要在发送查询之前展开值。
看看:http://blogs.msdn.com/b/alexj/archive/2009/03/26/tip-8-writing-where-in-style-queries-using-linq-to-entities.aspx
由于.NET 3.5不支持Contains,您可以使用动态Linq库,该库允许您使用字符串生成where子句。这样,你就不必摆弄所有的Expression行话了。
在NuGet上可用:https://www.nuget.org/packages/System.Linq.Dynamic.Library/.
你的Where条款看起来像这样:
.Where("CarStatusId=1 AND (CarId=1 OR CarId=2 OR CarId=3"))
您只需要根据toBeFilteredCarId列表生成该字符串。
您可以使用Any()
。虽然没有Contains()
那么优雅,但它在.NET3.5:中起到了作用
.Where(c => toBeFilteredCarIds.Any(g => g == c.CarId) && c.CarStatusId == 1);