簡體   English   中英

如何在 C# 中動態應用已注冊謂詞列表中的謂詞?

[英]How can I dynamically apply predicates from a list of registered predicates in C#?

我有一個IQueryable<T> T是泛型類型參數, where T: class, IEntity, new()

現在我有了這段代碼,它注冊了一個要動態應用於此可查詢對象的謂詞列表:

private static Dictionary<int, Action<IQueryable<IEntity>>> queryAugmenters = new Dictionary<int, Action<IQueryable<IEntity>>>();

public static List<Action<IQueryable<IEntity>>> QueryAugmenters
{
    get
    {
        return queryAugmenters.Values.ToList();
    }
}

public static void AddQueryAugmenter(Action<IQueryable<IEntity>> queryAugmenter)
{
    var hash = queryAugmenter.GetHashCode();
    if (queryAugmenters.ContainsKey(hash))
    {
        return;
    }
    queryAugmenters.Add(hash, queryAugmenter);
}

這是我注冊增強器的一個地方:

DynamicQuery.AddQueryAugmenter(queryable =>
{
    if (Config.HasMultipleLocales)
    {
        queryable = queryable.Where(i => ((ILocale)i).LocaleId == Config.LocaleId);
    }
});

所以,基本上我看到了設置,如果這個項目是多語言的,我會向IQueryable<T>添加一個謂詞。

這是我用來在給定查詢上應用增強器的代碼:

private static IQueryable<T> AugmentQuery(IQueryable<T> queryable)
{
    foreach (var queryAugmenter in DataAccessConfig.QueryAugmenters)
    {
        queryAugmenter.Invoke(queryable);
    }

    return queryable;
}

問題是它不起作用。

它編譯、運行,但沒有向發送到數據庫的查詢添加where 子句

如果我移動代碼,它會起作用:

private static IQueryable<T> AugmentQuery(IQueryable<T> queryable)
{
    foreach (var queryAugmenter in DataAccessConfig.QueryAugmenters)
    {
        queryAugmenter.Invoke(queryable);
    }

    // this code works here
    if (Config.HasMultipleLocales)
    {
        queryable = queryable.Where(i => ((ILocale)i).LocaleId == Config.LocaleId);
    }

    return queryable;
}

我在這里想念什么?

改變你的Action<IQueryable<IEntity>> fo Func<IQueryable<IEntity>, IQueryable<IEntity>>這樣你就可以鏈式調用

然后將AugmentQuery(IQueryable<T> queryable)更改為

private static IQueryable<T> AugmentQuery(IQueryable<T> queryable)
{
    foreach (var queryAugmenter in DataAccessConfig.QueryAugmenters)
    {
        queryable = queryAugmenter(queryable);
    }

    return queryable;
}

還有你當前的DynamicQuery.AddQueryAugmenter

queryable => Config.HasMultipleLocales ? queryable.Where(i => ((ILocale)i).LocaleId == Config.LocaleId) : queryable

換句話說,現在您的queryAugmenter應該遵循

queryable =>
{
    if(something)
    {
        queryable = queryable.Where(....);
    }
    return queryable;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM