تصفية حذف لينة من مجموعة دبكونتيكست ()
-
29-10-2019 - |
سؤال
كيف يمكنني تصفية IsSoftDeleted
البنود من هذا دبسيت?
var type = GetTypeFromString("Whatever");
var whatevers = Set(type);
الطريقة
public dynamic Set(Type type)
{
var set = dbContext.Set(type);
return set;
}
نموذج
public class Whatever : BaseEntity
{
public virtual string Name { get; set; }
}
public class BaseEntity
{
public virtual int Id { get; set; }
public virtual bool? IsSoftDeleted { get; set; }
}
تحرير:نسيت أن تظهر Whatever
مشتق من BaseEntity
المحلول
أيا كان الصف الخاص بك ليس لديه أي خاصية إيسوفتديليتد ، لذلك لا يوجد شيء لتصفية.سأفترض كل ما هو مشتق من باسينتيتي.
المشكلة الرئيسية هي أن إيكريابل<T>.حيث لا يوجد في الواقع:إنها طريقة تمديد ، وطرق التمديد لا تلعب بشكل جيد مع الأنواع الديناميكية.إذا كان المترجم يمكن أن يرى نوع ينفذ إكيريابل<T>، يمكنك كتابة فار.أين(...) ويكون المترجم حلها إلى النظام.لينق.قابل للاستعلام.كان (فار,...).وبما أن النوع ديناميكي في المثال الخاص بك ، فإن المترجم لا يعرف أنه ينفذ إكيريابل ، وسوف يبلغ عن خطأ عند محاولة استدعاء أين.
يمكنك يلقي دبسيت إلى إكيريابل<BaseEntity> (طالما أن النوع يحتوي على باسينتيتي كفئة أساسية) ، واستدعاء أي مرشح على ذلك.هل تستخدم بالفعل ميزة النوع الديناميكي?إذا لم يكن كذلك ، يمكنك أيضا النظر في إسقاط وظيفة مجموعة مخصصة ، واستخدام دبكونتيكست الافتراضي.تعيين وظيفة.
var query = (from e in (IQueryable<BaseEntity>)dbContext.Set(type)
where e.IsSoftDeleted != true
select e);
ملاحظة:هذا هو لا نفس استخدام دبكونتيكست.مجموعة (نوع).المصبوب<BaseEntity>():هذا لن يعمل ، لأن دبسيت<BaseEntity> و دبسيت<Whatever> غير متوافقة.هو فقط مع واجهات إكيريابل وغيرها مع "خارج" نوع الحجج التي يمكنك القيام بذلك.
نصائح أخرى
المشكلة هي أن Set(Type type)
إرجاع غير عام DbSet
.لتطبيق الفلتر الخاص بك ، يجب عليك إرساله إلى عام IQueryable<T>
:
var set = ((IQueryable<BaseEntity>)dbContext.Set(type))
.Where(be => be.IsSoftDeleted.HasValue && !be.IsSoftDeleted.Value);
هذا يعمل فقط إذا type
مشتق من BaseEntity
أو BaseEntity
نفسها ، وإلا ستحصل على استثناء وقت التشغيل.
الناتج set
هو من النوع IQueryable<BaseEntity>
, ، لذا فإن السؤال هو مدى فائدة هذه النتيجة وكيف يمكنك تطبيق المزيد من المرشحات للكيانات المشتقة مثل Where(w => w.Name == "abc")
.على الأقل ، لم أتمكن من الحصول على رمز قابل للتجميع بجعل set
من النوع dynamic
.كما أنني لا أود أن أفقد كل الكتابة القوية.