gpt4 book ai didi

linq - 使用具有规范模式的预先加载

转载 作者:行者123 更新时间:2023-12-04 01:03:29 24 4
gpt4 key购买 nike

我已经使用 Linq 实现了规范模式,如下所述 https://www.packtpub.com/article/nhibernate-3-using-linq-specifications-data-access-layer

我现在想添加急切加载的功能,但不确定最好的方法。

链接示例中的通用存储库类:

public IEnumerable<T> FindAll(Specification<T> specification)
{
var query = GetQuery(specification);
return Transact(() => query.ToList());
}

public T FindOne(Specification<T> specification)
{
var query = GetQuery(specification);
return Transact(() => query.SingleOrDefault());
}

private IQueryable<T> GetQuery(
Specification<T> specification)
{
return session.Query<T>()
.Where(specification.IsSatisfiedBy());
}

和规范实现:
public class MoviesDirectedBy : Specification<Movie>
{

private readonly string _director;

public MoviesDirectedBy(string director)
{
_director = director;
}

public override
Expression<Func<Movie, bool>> IsSatisfiedBy()
{
return m => m.Director == _director;
}
}

这运行良好,我现在想添加能够快速加载的功能。我知道可以使用 Fetch 来完成 NHibernate 的急切加载在查询上。

我正在寻找的是是否将急切加载逻辑封装在规范中或将其传递到存储库中,以及实现此目的所需的 Linq/表达式树语法(即如何完成的示例)。

最佳答案

一个可能的解决方案是扩展 Specification 类以添加:

public virtual IEnumerable<Expression<Func<T, object>>> FetchRelated
{
get
{
return Enumerable.Empty<Expression<Func<T, object>>>();
}
}

并将 GetQuery 更改为:
        return specification.FetchRelated.Aggregate(
session.Query<T>().Where(specification.IsSatisfiedBy()),
(current, related) => current.Fetch(related));

现在您要做的就是在需要时覆盖 FetchRelated
public override IEnumerable<Expression<Func<Movie, object>>> FetchRelated
{
get
{
return new Expression<Func<Movie, object>>[]
{
m => m.RelatedEntity1,
m => m.RelatedEntity2
};
}
}

我刚刚写的这个实现的一个重要限制是你只能获取与根实体直接相关的实体。

一个改进是支持任意级别(使用 ThenFetch ),这需要对我们使用泛型的方式进行一些更改(我使用 object 以允许轻松组合不同的实体类型)

关于linq - 使用具有规范模式的预先加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4363467/

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