第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使用可查詢。在運行時設(shè)置類型時的位置?

如何使用可查詢。在運行時設(shè)置類型時的位置?

C#
呼啦一陣風 2022-08-20 16:59:27
我正在使用 EF6 為應(yīng)用實現(xiàn)搜索/篩選 UI 的后端。我有一些代碼可以構(gòu)建一個表達式來與Queryable一起使用。對于給定的DbSet,DbSet的類型是在運行時確定的(DBContext有很多,它們可能會改變)。如果我通過先將表達式轉(zhuǎn)換為特定類型來作弊,則對 Where 的調(diào)用工作正常。否則,我得到這個錯誤:'System.Linq.Queryable.Where(System.Linq.IQueryable, System.Linq.Expressions.Expression>)'的最佳重載方法匹配有一些無效參數(shù)”我正在努力尋找一種方法來過濾DbSet,就像這樣,其中底層的“表”類型是在運行時提供的。下面是一個非常簡化的代碼版本來說明:    void ProcessFilter(AppDbContext context, NameValueCollection filters, Type tableType)    {        // If tableType == typeof(Organisation), expression is a Expression<Func<Organisation, bool>>        var expression = GetFilterExpression(filters);        var dbset = Set(context, tableType);        dynamic dynamicSet = dbset;        // This fails        var results = Queryable.Where(dynamicSet, expression);        // see https://stackoverflow.com/questions/4285598/iqueryable-non-generic-missing-count-and-skip-it-works-with-iqueryablet        // Suppose tableType == typeof(Organisation)        // This works        var typedExpression = expression as Expression<Func<Organisation, bool>>;        var typedResults = Queryable.Where(dynamicSet, typedExpression);    }    public static IQueryable Set(DbContext context, Type T)    {        // Similar to code in        // https://stackoverflow.com/questions/21533506/find-a-specified-generic-dbset-in-a-dbcontext-dynamically-when-i-have-an-entity        var method = typeof(DbContext).GetMethods(BindingFlags.Public | BindingFlags.Instance).Where(x => x.Name == "Set" && x.IsGenericMethod).First();        // Build a method with the specific type argument         method = method.MakeGenericMethod(T);        return method.Invoke(context, null) as IQueryable;    }
查看完整描述

2 回答

?
慕容708150

TA貢獻1831條經(jīng)驗 獲得超4個贊

回答你的具體問題。鑒于

IQueryable source
LambdaExpression predicate

如何調(diào)用靜態(tài)泛型方法

Queryable.Where<T>(IQueryable<T> source, Expression<Func<T, bool>> predicate)

它可以使用(A)反射,(B)DLR動態(tài)調(diào)度和(C)來完成。Expression.Call

您要做的是選項(B)。然而

var result = Queryable.Where((dynamic)source, predicate);

對具有類型第二個參數(shù)的方法進行動態(tài)搜索,這當然會失敗。LambdaExpression

為了能夠動態(tài)匹配目標方法,您還需要創(chuàng)建第二個參數(shù):dynamic

var result = Queryable.Where((dynamic)source, (dynamic)predicate);

上述等效選項(C)的實現(xiàn)是:

var result = source.Provider.CreateQuery(Expression.Call( 
   typeof(Queryable), nameof(Queryable.Where), new[] { source.ElementType },
    source.Expression, predicate));


查看完整回答
反對 回復(fù) 2022-08-20
?
GCT1015

TA貢獻1827條經(jīng)驗 獲得超4個贊

恭喜你的第一個問題。


讓我們首先看一下基于某些自定義篩選器篩選數(shù)據(jù)集合的方法。我將假設(shè)您更喜歡傳入篩選器,將屬性名稱保存為鍵,將屬性值保存為值。NameValueCollectionType


在繼續(xù)篩選整個集合之前,讓我們首先弄清楚如何確定一個對象是否具有與篩選器匹配的屬性。由于我們直到運行時才知道對象,因此我們需要在 C# 中使用泛型來實現(xiàn)此目的。Type


步驟1

- 獲取所有類屬性

我們需要獲取泛型類的所有屬性,例如 .使用反射執(zhí)行此操作被認為是緩慢的,Matt Warren解釋了為什么反射在.NET中很慢以及如何解決它。因此,我們將實現(xiàn)類組件模型的緩存,以獲取其存在于命名空間 System.ComponentModel.PropertyDescriptorCollection 中的類組件模型。<TClass>PropertyDescriptorCollection


組件緩存


private static IDictionary<string, PropertyDescriptorCollection> _componentsCache

        = new Dictionary<string, PropertyDescriptorCollection>();

我們的鍵表示泛型類的名稱,值保存該給定類的名稱。DictionaryPropertyDescriptorCollection


internal static bool InnerFilter<T>(T obj, NameValueCollection filters)

        where T : class

{

        Type type = typeof(T);

        PropertyDescriptorCollection typeDescriptor = null;


        if (_componentsCache.ContainsKey(type.Name))

            typeDescriptor = _componentsCache[type.Name];

        else

        {

            typeDescriptor = TypeDescriptor.GetProperties(type);

            _componentsCache.Add(type.Name, typeDescriptor);

        }

}

步驟2

- 循環(huán)通過過濾器

在獲取了變量中泛型類(如上所示)后,現(xiàn)在讓我們遍歷篩選器,看看其任何屬性名稱是否與任何篩選器鍵匹配。如果屬性名稱與任何篩選器鍵匹配,則現(xiàn)在我們檢查屬性的實際值是否與篩選器值匹配。為了提高搜索/篩選函數(shù)的質(zhì)量,我們將在 C# 中使用正則表達式來確定比較是命中還是未命中。PropertyDescriptorCollectionTtypeDescriptorT


for (int i = 0; i < filters.Count; i++)

{

    string filterName = filters.GetKey(i);

    string filterValue = filters[i];


    PropertyDescriptor propDescriptor = typeDescriptor[filterName];

    if (propDescriptor == null)

        continue;

    else

    {

        string propValue = propDescriptor.GetValue(obj).ToString();

        bool isMatch = Regex.IsMatch(propValue, $"({filterValue})");

        if (isMatch)

            return true;

        else

            continue;

    }

}

步驟3

- 實現(xiàn)擴展方法。

為了使我們編寫的代碼易于使用和重用,我們將在 C# 中實現(xiàn)擴展方法,以便我們可以在項目中的任何位置更好地重用我們的函數(shù)。


- 使用上述函數(shù)的通用集合篩選器函數(shù)。

由于 可以通過 .函數(shù)在 中,我們將在函數(shù)調(diào)用中使用它,如下所示。IQueryable<T>IEnumerable<T>Where()System.Linq


public static IEnumerable<T> Filter<T>(this IEnumerable<T> collection, NameValueCollection filters)

        where T : class

{

    if (filters.Count < 1)

        return collection;


    return collection.Where(x => x.InnerFilter(filters));

}

步驟4

將所有內(nèi)容放在一起。

現(xiàn)在我們已經(jīng)擁有了所需的一切,讓我們看看最終/完整代碼在單個類中如何看起來像一個代碼塊。static


public static class Question54484908 

{

    private static IDictionary<string, PropertyDescriptorCollection> _componentsCache = new Dictionary<string, PropertyDescriptorCollection> ();


    public static IEnumerable<T> Filter<T> (this IEnumerable<T> collection, NameValueCollection filters)

        where T : class 

    {

        if (filters.Count < 1)

            return collection;


        return collection.Where (x => x.InnerFilter (filters));

    }


    internal static bool InnerFilter<T> (this T obj, NameValueCollection filters)

        where T : class 

    {

        Type type = typeof (T);

        PropertyDescriptorCollection typeDescriptor = null;


        if (_componentsCache.ContainsKey (type.Name))

            typeDescriptor = _componentsCache[type.Name];

        else {

            typeDescriptor = TypeDescriptor.GetProperties (type);

            _componentsCache.Add (type.Name, typeDescriptor);

        }


        for (int i = 0; i < filters.Count; i++) {

            string filterName = filters.GetKey (i);

            string filterValue = filters[i];


            PropertyDescriptor propDescriptor = typeDescriptor[filterName];

            if (propDescriptor == null)

                continue;

            else {

                string propValue = propDescriptor.GetValue (obj).ToString ();

                bool isMatch = Regex.IsMatch (propValue, $"({filterValue})");

                if (isMatch)

                    return true;

                else

                    continue;

            }

        }


        return false;

    }

}

最后

過濾 、 、 數(shù)組IEnumerable<T>List<T>

這就是您將在項目中的任何位置使用上述代碼的方式。


private IEnumerable<Question> _questions;

_questions = new List<Question>()

{

    new Question("Question 1","How do i work with tuples"),

    new Question("Question 2","How to use Queryable.Where when type is set at runtime?")

};

var filters = new NameValueCollection 

   { "Description", "work" }

};

var results = _questions.Filter(filters);

濾波DbSet<T>

每個都有一個函數(shù),該函數(shù)返回可以用作 a 的函數(shù),因此我們的函數(shù)可以使用,如下所示。DbContext.Set<T>DbSet<T>IQueryable<T>



_dbContext.Set<Question>().Filter(filters);

希望這能回答你的問題,或者更確切地說,為你指出正確的方向。


查看完整回答
反對 回復(fù) 2022-08-20
  • 2 回答
  • 0 關(guān)注
  • 110 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號