سؤال

مستوحى من واجهة متجر MVC، أحدث مشروع أعمل عليه هو استخدام طرق الامتداد في IQueryable لتصفية النتائج.

لدي هذه الواجهة؛

IPrimaryKey
{
  int ID { get; }
}

ولدي طريقة التمديد هذه

public static IPrimaryKey GetByID(this IQueryable<IPrimaryKey> source, int id)
{
    return source(obj => obj.ID == id);
}

لنفترض أن لدي فئة SimpleObj التي تنفذ IPrimaryKey.عندما يكون لدي IQueryable لـ SimpleObj، فإن أسلوب GetByID غير موجود، إلا إذا قمت بشكل صريح بتحويل IQueryable لـ IPrimaryKey، وهو أقل من مثالي.

نسيت شيئا ما هنا؟

هل كانت مفيدة؟

المحلول

إنه يعمل عندما يتم القيام به بشكل صحيح.يعمل حل cfeduke.ومع ذلك، ليس عليك القيام بذلك IPrimaryKey الواجهة عامة، في الواقع، ليس عليك تغيير تعريفك الأصلي على الإطلاق:

public static IPrimaryKey GetByID<T>(this IQueryable<T> source, int id) where T : IPrimaryKey
{
    return source(obj => obj.ID == id);
}

نصائح أخرى

يحرر: كونرادالحل أفضل لأنه أبسط بكثير.يعمل الحل أدناه ولكنه مطلوب فقط في المواقف المشابهة لـ ObjectDataSource حيث يتم استرداد طريقة الفصل من خلال الانعكاس دون السير في التسلسل الهرمي للميراث.من الواضح أن هذا لا يحدث هنا.

هذا ممكن، لقد اضطررت إلى تنفيذ نمط مماثل عندما قمت بتصميم حل إطار عمل كيان مخصص للعمل مع ObjectDataSource:

public interface IPrimaryKey<T> where T : IPrimaryKey<T>
{
    int Id { get; }
}

public static class IPrimaryKeyTExtension
{
     public static IPrimaryKey<T> GetById<T>(this IQueryable<T> source, int id) where T : IPrimaryKey<T>
     {
         return source.Where(pk => pk.Id == id).SingleOrDefault();
     }
}

public class Person : IPrimaryKey<Person>
{
    public int Id { get; set; }
}

مقتطف من الاستخدام:

var people = new List<Person>
{
    new Person { Id = 1 },
    new Person { Id = 2 },
    new Person { Id = 3 }
};

var personOne = people.AsQueryable().GetById(1);

لا يمكن أن ينجح هذا نظرًا لأن الأدوية الجنيسة لا تملك القدرة على متابعة أنماط الوراثة.أي.IQueryable<SimpleObj> غير موجود في شجرة الوراثة لـ IQueryable<IPrimaryKey>

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top