如何使用EF快捷查询建筑
本文关键字:查询 建筑 何使用 EF | 更新日期: 2023-09-27 18:01:09
我有一个保存用户输入的模型,我有使用EF的这些数据构建数据库查询。所有参数都是可选的。
我的问题是:查询构建可以用更短的方式完成吗?
带用户输入的型号:
public class PostFilterModel
{
public PostFilterModel()
{
Currency = Enumerable.Empty<Currency>();
Condition = Enumerable.Empty<Condition>();
Transmission = Enumerable.Empty<Transmission>();
Rudder = Enumerable.Empty<Rudder>();
Body = Enumerable.Empty<Body>();
Engine = Enumerable.Empty<Engine>();
Gear = Enumerable.Empty<Gear>();
}
public int City { get; set; }
public int Region { get; set; }
public int Brand { get; set; }
public int Model { get; set; }
public int MinHorsePower { get; set; }
public int MaxHorsePower { get; set; }
public int MinEngineCapacity { get; set; }
public int MaxEngineCapacity { get; set; }
public int MinMileage { get; set; }
public int MaxMileage { get; set; }
public int MinPrice { get; set; }
public int MaxPrice { get; set; }
public int MinYear { get; set; }
public int MaxYear { get; set; }
public IEnumerable<Currency> Currency { get; set; }
public IEnumerable<Condition> Condition { get; set; }
public IEnumerable<Transmission> Transmission { get; set; }
public IEnumerable<Rudder> Rudder { get; set; }
public IEnumerable<Body> Body { get; set; }
public IEnumerable<Engine> Engine { get; set; }
public IEnumerable<Gear> Gear { get; set; }
}
我的基于模型的查询生成器:
public ICollection<Post> GetByFilter(PostFilterModel filter)
{
IQueryable<Post> Posts = uow.PostRepository.GetAll();
if (filter.City > 0)
Posts = Posts.Where(p => p.City.CityId == filter.City);
if (filter.Region > 0)
Posts = Posts.Where(p => p.City.Region.RegionId == filter.Region);
if (filter.Brand > 0)
Posts = Posts.Where(p => p.Car.Brand.BrandId == filter.Brand);
if (filter.Model > 0)
Posts = Posts.Where(p => p.Car.Model.ModelId == filter.Model);
if (filter.MinPrice > 0)
Posts = Posts.Where(p => p.Price >= filter.MinPrice);
if (filter.MaxPrice > 0)
Posts = Posts.Where(p => p.Price <= filter.MaxPrice);
if (filter.MinYear > 0)
Posts = Posts.Where(p => p.Car.Year >= filter.MinYear);
if (filter.MaxYear > 0)
Posts = Posts.Where(p => p.Car.Year <= filter.MaxYear);
if (filter.Condition.Count() > 0)
Posts = Posts.Where(p => filter.Condition.Contains(p.Car.Condition));
if (filter.Transmission.Count() > 0)
Posts = Posts.Where(p => filter.Transmission.Contains(p.Car.Transmission));
if (filter.Rudder.Count() > 0)
Posts = Posts.Where(p => filter.Rudder.Contains(p.Car.Rudder));
if (filter.Body.Count() > 0)
Posts = Posts.Where(p => filter.Body.Contains(p.Car.Body));
if (filter.Engine.Count() > 0)
Posts = Posts.Where(p => filter.Engine.Contains(p.Car.Engine));
if (filter.Gear.Count() > 0)
Posts = Posts.Where(p => filter.Gear.Contains(p.Car.Gear));
return Posts.ToList();
}
我不知道你为什么想要使用更少的代码,我更喜欢可读性而不是更少的代码。在不太破坏可读性的情况下,我唯一能想到的就是将所有逻辑组合成一个Where子句,比如:
public ICollection<Post> GetByFilter(PostFilterModel filter)
{
return uow.PostRepository.GetAll().Where(p =>
(filter.City <= 0 || p.City.CityId == filter.City) &&
(filter.Region <= 0 || p.Region.RegionId == filter.Region) &&
(filter.Brand <= 0 || p.Car.Brand.BrandId == filter.Brand) &&
(filter.Model <= 0 || p.Car.Model.ModelId == filter.Model) &&
(filter.MinPrice <= 0 || p.Price >= filter.MinPrice) &&
(filter.MaxPrice <= 0 || p.Price <= filter.MaxPrice) &&
(filter.MinYear <= 0 || p.Car.Year >= filter.MinYear) &&
(filter.MaxYear <= 0 || p.Car.Year <= filter.MaxYear) &&
(filter.Condition.Count() <= 0 || filter.Condition.Contains(p.Car.Condition)) &&
(filter.Transmission.Count() <= 0 || filter.Transmission.Contains(p.Car.Transmission)) &&
(filter.Rudder.Count() <= 0 || filter.Rudder.Contains(p.Car.Rudder)) &&
(filter.Body.Count() <= 0 || filter.Body.Contains(p.Car.Body)) &&
(filter.Engine.Count() <= 0 || filter.Engine.Contains(p.Car.Engine)) &&
(filter.Gear.Count() <= 0 || filter.Gear.Contains(p.Car.Gear)) &&
);
}
但你实际上并没有存多少钱。
您可以通过在过滤器上存储子句来使用查询的动态生成,但这只是将代码转移到其他地方,并在代码中构建依赖关系。
我恳请您不要使用单行if语句(即没有大括号(,因为这是一个等待发生的错误。
我的观点是,保持代码可读性而不是简短。