توليد التعبير <> للتصفية بواسطة خاصية تعسفية
-
05-07-2019 - |
سؤال
أريد أن أكتب عناصر التحكم في التصفية التي تأخذ نوع الكائن T
واسم الممتلكات والعودة Expression<Func<T, bool>>
أن يتحقق قيمة الخاصية التي تم تمريرها. لا أريد استخدام التفكير لأنني أخشى أن لا يمكن استخدام هذه التعبيرات بواسطة EF. لا يمكنني استخدام المندوبين لأن C# ليس لديه مندوبون للممتلكات. ماذا يمكنني أن أفعل؟ ربما يجب أن أستخدم نهجًا مختلفًا لكتابة عناصر التحكم هذه؟
هذا هو نهج لي الأول باستخدام الانعكاس:
public string FilteringField { get; set; }
public Expression<Func<T, bool>> GetFilterExpression()
{
if (cmbValue.SelectedIndex == 1)
return (o => (bool)typeof(T).GetProperty(FilteringField).GetValue(o, null));
if (cmbValue.SelectedIndex == 2)
return (o => !(bool)typeof(T).GetProperty(FilteringField).GetValue(o, null));
return null;
}
المحلول
الانعكاس ليس مشكلة هنا ؛ لن تتمكن EF من ملاحظة الفرق. نهج المندوب هو غير مستمر ، بالمناسبة (بما أنك ذكرت EF) ؛ في النهاية ، إنه شيء مثل:
public static IQueryable<T> Where<T>(this IQueryable<T> query,
string propertyName, object value)
{
PropertyInfo prop = typeof(T).GetProperty(propertyName);
var param = Expression.Parameter(typeof(T), "x");
var body = Expression.Equal(
Expression.Property(param, prop),
Expression.Constant(value, prop.PropertyType)
);
var predicate = Expression.Lambda<Func<T, bool>>(body, param);
return query.Where(predicate);
}
لاحظ أنه يمكنك تسهيله Expression.PropertyOrField(propertyName)
; ؛ السبب في أنني لم أستخدم هذا هنا هو أنه من المفيد للغاية معرفة نوع العضو (prop.PropertyType
) عند إنشاء الثابت - وإلا يمكنك الحصول على مشاكل مع Nulls.
نصائح أخرى
أعلم أن هذه إجابة قديمة ولكن إذا رأى شخص ما أن هذا قد بني هذا المشروع:
https://github.com/poweredsoft/dynamiclinq
التي يجب تنزيلها على Nuget أيضًا:
https://www.nuget.org/packages/poweredsoft.dynamiclinq
ويمكنك القيام ببساطة
query.Where("FirstName", ConditionOperators.Equal, "David");