gpt4 book ai didi

c# - 使用 Entity Framework 并使用 orderby 和 skip/take 的规范模式

转载 作者:太空狗 更新时间:2023-10-29 20:20:24 25 4
gpt4 key购买 nike

我选择了一个使用规范模式的项目,这是一个我以前没有使用过的模式,我不得不去研究这个模式。我注意到它没有 OrderBySkip/Take 功能,而且我找不到任何显示如何使用该模式实现此功能的地方。

我正在努力思考如何最好地将其添加到规范模式中。但是我遇到了问题,比如规范处理“Expression<Func<T, bool>>”,而我认为我不能将它与 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 子句。它还允许使用“和”、“或”链接规则。例如:

var spec = new Specification<Wave>(w => w.Id == "1").And(w => w.WaveStartSentOn > DateTime.Now);

如何为“OrderBy”和“Take”添加方法?

因为这是现有代码,我不能做任何会影响现有代码的更改,重构它是一项艰巨的工作。因此,任何解决方案都需要能够很好地发挥现有的作用。

最佳答案

怎么样

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”值不会丢失

然后你的 Satisfying 方法变成:

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:检查“Prepare”方法中的 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);

关于c# - 使用 Entity Framework 并使用 orderby 和 skip/take 的规范模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25244030/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com