我已经选择了一个使用规范模式的项目,这是我之前没有使用的模式,我不得不去研究模式.我注意到它没有orderby和skip / take功能,我找不到任何显示如何用模式实现它的地方.
我正在努力思考如何将其添加到规范模式中.但是我遇到过问题,例如规范处理“Expression>”而我认为我不能将它与orderby等一起存储
基本上有一个这样的类:
public class Specification<T> : ISpecification<T> { public Expression<Func<T,bool>> Predicate { get; protected set; } public Specification(Expression<Func<T,bool>> predicate) { Predicate = predicate; } public Specification<T> And(Specification<T> specification) { return new Specification<T>(this.Predicate.And(specification.Predicate)); } public Specification<T> And(Expression<Func<T,bool>> predicate) { return new Specification<T>(this.Predicate.And(predicate)); } public Specification<T> Or(Specification<T> specification) { return new Specification<T>(this.Predicate.Or(specification.Predicate)); } public Specification<T> Or(Expression<Func<T,bool>> predicate) { return new Specification<T>(this.Predicate.Or(predicate)); } public T SatisfyingItemFrom(IQueryable<T> query) { return query.Where(Predicate).SingleOrDefault(); } public IQueryable<T> SatisfyingItemsFrom(IQueryable<T> query) { return query.Where(Predicate); } }
这允许创建一个规范,传入一个where子句.它还允许使用“And”,“Or”链接规则.例如:
var spec = new Specification<Wave>(w => w.Id == "1").And(w => w.WaveStartSentOn > DateTime.Now);
由于这是现有代码,我不能做任何会影响现有代码的更改,重构它将是一项非常重要的工作.所以任何解决方案都需要很好地发挥作用.
解决方法
怎么样
public class Specification<T> : ISpecification<T> { public Expression<Func<T,bool>> Predicate { get; protected set; } public Func<IQueryable<T>,IOrderedQueryable<T>> Sort {get; protected set; } public Func<IQueryable<T>,IQueryable<T>> PostProcess {get; protected set; public Specification<T> OrderBy<TProperty>(Expression<Func<T,TProperty>> property) { var newSpecification = new Specification<T>(Predicate) { PostProcess = PostProcess } ; if(Sort != null) { newSpecification.sort = items => Sort(items).ThenBy(property); } else { newSpecification.sort = items => items.OrderBy(property); } return newSpecification; } public Specification<T> Take(int amount) { var newSpecification = new Specification<T>(Predicate) { Sort = Sort } ; if(PostProcess!= null) { newSpecification.PostProcess= items => PostProcess(items).Take(amount); } else { newSpecification.PostProcess= items => items.Take(amount); } return newSpecification; } public Specification<T> Skip(int amount) { var newSpecification = new Specification<T>(Predicate) { Sort = Sort } ; if(PostProcess!= null) { newSpecification.PostProcess= items => PostProcess(items).Skip(amount); } else { newSpecification.PostProcess= items => items.Skip(amount); } return newSpecification; } }
去做:
> OrderByDescending的类似结构
>更新您的其他方法,以便在调用“And”时不会丢失“Sort”值和“PostProcess”值,例如
然后你满意的方法变成:
private IQueryable<T> Prepare(IQueryable<T> query) { var filtered = query.Where(Predicate); var sorted = Sort(filtered); var postProcessed = PostProcess(sorted); return postProcessed; } public T SatisfyingItemFrom(IQueryable<T> query) { return Prepare(query).SingleOrDefault(); } public IQueryable<T> SatisfyingItemsFrom(IQueryable<T> query) { return Prepare(query); }
Todo:检查Sort& “准备”方法中的PostProcess不为空
用法:
var spec = new Specification<Wave>(w => w.Id == "1") .And(w => w.WaveStartSentOn > DateTime.Now) .OrderBy(w => w.WaveStartSentOn) .Skip(20) .Take(5);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。