0

目前,要使用 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)。我找不到更好的方法来根据用户输入进行搜索,而不是不断检查输入是否存在(添加到搜索参数))然后在当前查询中添加新的位置。谁能告诉我是否有更好的方法来做到这一点?谢谢!

4

1 回答 1

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或者我相信您可以通过分离过滤器逻辑和使用方法来使其更加标准。可以在此处找到在实体框架上实现存储库/规范的良好框架。

于 2012-07-13T03:04:25.367 回答