目前,要使用EF CodeFirst和存储库模式进行搜索,根据用户对mvc搜索视图/页面上多个文本框的输入,我执行以下操作:
public PagedList<Entity1> PlayerUserSearch(Entity1SearchParameters searchParameters, int? pageSize, int? startEntity, Func<Entity1, object> sortOrder, bool sortDesc)
{
IQueryable<Entity1> query = from entities in this.DataContext.Entity1s.Include("Entity2List")
where entities.Entity2List.Any()
select entities;
if (searchParameters.Entity2PrimaryKeyId.HasValue)
query = query.Where(e => e.Id == searchParameters.Entity2PrimaryKeyId.Value);
if (searchParameters.HasStats.HasValue)
{
if (searchParameters.HasStats.Value)
query = query.Where(u => u.Entity2List.Any(e => e.Stat != null));
else
query = query.Where(u => u.Entity2List.Any(e => e.Stat == null));
}
if (searchParameters.Entity2OtherField.HasValue)
query = query.Where(u => u.Entity2List.Any(e => e.Event.Entity2OtherField == searchParameters.Entity2OtherField));
if (searchParameters.Entity2OtherField2.HasValue)
query = query.Where(u => u.Entity2List.Any(e => e.Event.Entity2OtherField2 == searchParameters.Entity2OtherField2));
if (searchParameters.Active.HasValue)
query = query.Where(e => e.Active == searchParameters.Active.Value);
return this.GetPageByStartEntity(pageSize.Value, startEntity.Value, query, sortOrder, sortDesc);
}
这个问题是,每次我添加另一个检查某个字段的Entity1(Entity2)的子节点的地方时,它会对生成的sql语句采用新的“AND EXISTS”子句,以便它正在为每个检查的不同字段重复执行存在和检查表Entity2,而不是在查询中对Entity执行单个EXISTS,并检查我添加到查询的所有字段(即EntityOtherField1和EntityOtherField2)。我无法找到一种更好的方法来进行基于用户输入的搜索,而不是不断地检查那里的输入(添加到搜索参数))然后添加到当前查询的新位置。谁能告诉我是否有更好的方法来做到这一点?谢谢!
答案 0 :(得分:0)
我认为您正在寻找的是使用规范模式。
var spec = new specification<Entity2>(s => true);
if (searchParameters.HasStats.Value)
{
spec = spec.And(e => e.Stat != null);
}
if (searchParameters.Entity2OtherField2.HasValue)
{
spec = spec.And(e => e.Event.Entity2OtherField2 == searchParameters.Entity2OtherField2);
}
query = query.Where(u => u.Entity2List.Any(spec));
或者我相信你可以通过分离过滤器逻辑和使用spec.IsStatisfiedBy
方法使其更加标准化。
可以在here找到实体框架上存储库/规范实现的良好框架。