0

我有一个带有返回 IQueryable 的查询方法的通用存储库。在我的调用代码中,我可以做这样的事情

_repository.Query<MyClass>(x=>x.EntityId == 1).Fetch(x=>x.MyClassChild).ToList()

但是,我将无法测试调用代码(据我所知)。所以我正在尝试执行以下操作

public class Repository : IRepository
{
....
    public FetchedResult<TQueried, TRelated> ThenFetch<TQueried, TFetch, TRelated>(INhFetchRequest<TQueried, TFetch> query, Expression<Func<TFetch, TRelated>> relatedObjectSelector)
    {
        INhFetchRequest<TQueried, TRelated> nhFetchRequest = query.ThenFetch(relatedObjectSelector);
        return new FetchedResult<TQueried, TRelated>(this, nhFetchRequest);
    }

    public FetchedResult<TOriginating, TRelated> Fetch<TOriginating, TRelated>(IQueryable<TOriginating> query, Expression<Func<TOriginating, TRelated>> relatedObjectSelector)
    {
        INhFetchRequest<TOriginating, TRelated> nhFetchRequest = query.Fetch(relatedObjectSelector);
        return new FetchedResult<TOriginating, TRelated>(this, nhFetchRequest);
    }
}

--

public class FetchedResult<TQueried, TRelated>
{
    private readonly IRepository _repository;
    private readonly INhFetchRequest<TQueried, TRelated> _query;

    public FetchedResult(IRepository repository, INhFetchRequest<TQueried, TRelated> query)
    {
        _repository = repository;
        _query = query;
    }

    public FetchedResult<TQueried, TRelated> ThenFetch<TFetch>(Expression<Func<TFetch,TRelated>> relatedObjectSelector)
    {
        return _repository.ThenFetch(_query, relatedObjectSelector);
    }
}

因此,第一次调用 Fetch 有效,但调用 repositor.ThenFetch 接受 INhFetchRequest 查询,但返回 INhFetchRequest。所以我不能再使用 FetchedResult 再次调用 ThenFetch 。

我认为这是问题所在。在这一点上,我的大脑非常混乱。如果有人可以帮助让我知道,我可以尝试提供更多或更好的信息。

现在我知道我可以使用静态来做到这一点,但是我的目标是能够模拟对 Fetch 的调用。

谢谢,

拉伊夫

4

1 回答 1

0

好吧,我那微弱的大脑终于找到了解决办法。经过无聊的通勤后,我意识到问题在于泛型位于对象级别而不是方法级别。以下是我的解决方案。我可能会就上述问题发表博客,在这种情况下,稍后我将包含链接

public class Repository : IRepository
{
....
    public FetchQuery QueryFetch<ENTITY>(Expression<Func<ENTITY, bool>> where = null) where ENTITY : Entity
    {
        var query = _unitOfWork.CurrentSession.Query<ENTITY>();
        var queryable = where == null ? query : query.Where(where);
        return new FetchQuery(this, queryable);
    }

    public FetchedResult ThenFetch<TQueried, TFetch, TRelated>(INhFetchRequest<TQueried, TFetch> query, Expression<Func<TFetch, TRelated>> relatedObjectSelector)
    {
        INhFetchRequest<TQueried, TRelated> nhFetchRequest = query.ThenFetch(relatedObjectSelector);
        return new FetchedResult(this, nhFetchRequest);
    }

    public FetchedResult ThenFetchMany<TQueried, TFetch, TRelated>(INhFetchRequest<TQueried, TFetch> query, Expression<Func<TFetch, IEnumerable<TRelated>>> relatedObjectSelector)
    {
        INhFetchRequest<TQueried, IEnumerable<TRelated>> nhFetchRequest = query.ThenFetch(relatedObjectSelector);
        return new FetchedResult(this, nhFetchRequest);
    }

    public FetchedResult Fetch<TOriginating, TRelated>(IQueryable<TOriginating> query, Expression<Func<TOriginating, TRelated>> relatedObjectSelector)
    {
        INhFetchRequest<TOriginating, TRelated> nhFetchRequest = query.Fetch(relatedObjectSelector);
        return new FetchedResult(this, nhFetchRequest);
    }

    public FetchedResult FetchMany<TOriginating, TRelated>(IQueryable<TOriginating> query, Expression<Func<TOriginating, IEnumerable<TRelated>>> relatedObjectSelector)
    {
        INhFetchRequest<TOriginating, TRelated> nhFetchRequest = query.FetchMany(relatedObjectSelector);
        return new FetchedResult(this, nhFetchRequest);
    }
}

public class FetchedResult
{
    private readonly IRepository _repository;
    private object _query;
    public FetchedResult(IRepository repository, object query)
    {
        _repository = repository;
        _query = query;
    }

    public FetchedResult ThenFetch<TQueried, TFetch, TRelated>(Expression<Func<TFetch, TRelated>> relatedObjectSelector)
    {
        return _repository.ThenFetch((INhFetchRequest<TQueried, TFetch>)_query, relatedObjectSelector);
    }

    public FetchedResult ThenFetchMany<TQueried, TFetch, TRelated>(Expression<Func<TFetch, IEnumerable<TRelated>>> relatedObjectSelector)
    {
        return _repository.ThenFetchMany((INhFetchRequest<TQueried, TFetch>)_query, relatedObjectSelector);
    }

    public List<TOriginating> ToList<TOriginating>()
    {
        return ((IQueryable<TOriginating>)_query).ToList();
    }
}

public class FetchQuery
{
    private readonly IRepository _repository;
    private readonly object _query;

    public FetchQuery(IRepository repository, object query)
    {
        _repository = repository;
        _query = query;
    }

    public FetchedResult Fetch<TOriginating, TRelated>(Expression<Func<TOriginating, TRelated>> relatedObjectSelector)
    {
        return _repository.Fetch((IQueryable<TOriginating>)_query, relatedObjectSelector);
    }

    public FetchedResult FetchMany<TOriginating, TRelated>(Expression<Func<TOriginating, IEnumerable<TRelated>>> relatedObjectSelector)
    {
        return _repository.FetchMany((IQueryable<TOriginating>)_query, relatedObjectSelector);
    }

    public List<TOriginating> ToList<TOriginating>()
    {
        return ((IQueryable<TOriginating>) _query).ToList();
    }
}

用法如下

_repository.QueryFetch<InternetProfile>(x => x.CompanyId == Id ).FetchMany<InternetProfile, SiteProperty>(x => x.SiteProperties).ToList<InternetProfile>();

我确实发现泛型声明有点冗长,但它非常有效,我暂时将其保留。当然,任何建议都会受到欢迎。

拉伊夫

于 2013-06-19T14:20:04.327 回答