سؤال

أنا مرتبك فيما يتعلق بالفرق. كونها جديدة إلى حد ما على .NET، وأنا أعلم أنني أستطيع الاستعلام IEnumerables باستخدام ملحقات LINQ. إذن ما هذا IQueryable وكيف تختلف؟


أنظر أيضا ما هو الفرق بين iqueryable [t] و ienumerable [t]؟ التي تتداخل مع هذا السؤال.

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

المحلول

IEnumerable<T> يمثل مؤشرا للأمام فقط من T. وبعد .NET 3.5 طرق تمديد الإضافية التي تضمنت LINQ standard query operators مثل Where و First, مع أي مشغلين يتطلبون المتداول أو الوظائف المجهولة Func<T>.

IQueryable<T> ينفذ نفس مشغلي الاستعلام القياسي LINQ، ولكن يقبل Expression<Func<T>> للندوات والوظائف المجهولة. Expression<T> هي شجرة تعبير مترجمة، إصدار مكسور من الأسلوب ("نصف مترجمة" إذا كنت سوف) التي يمكن تحليلها بواسطة مزود Queroyable واستخدامها وفقا لذلك.

علي سبيل المثال:

IEnumerable<Person> people = GetEnumerablePeople();
Person person = people.Where(x => x.Age > 18).FirstOrDefault();

IQueryable<Person> people = GetQueryablePeople();
Person person = people.Where(x => x.Age > 18).FirstOrDefault();

في الكتلة الأولى، x => x.Age > 18 هي طريقة مجهولة (Func<Person, bool>)، والتي يمكن تنفيذها مثل أي طريقة أخرى. Enumerable.Where سوف تنفذ الطريقة مرة واحدة لكل شخص، yieldجي القيم التي عادت الطريقة true.

في الكتلة الثانية، x => x.Age > 18 هي شجرة التعبير (Expression<Func<Person, bool>>)، والتي يمكن اعتبارها "هي" العقار "العمر"> 18 ".

يتيح ذلك أشياء مثل LinQ-to-sql موجودة لأنها يمكن أن تحفيها شجرة التعبير وتحويلها إلى SQL المكافئ. ولأن المزود لا يحتاج إلى التنفيذ حتى IQueryable يتم تعداد (تنفذ IEnumerable<T>, بعد كل شيء)، يمكن أن الجمع بين مشغلي الاستعلام المتعدد (في المثال أعلاه Where و FirstOrDefault) اتخاذ خيارات أكثر ذكاء حول كيفية تنفيذ الاستعلام بأكمله مقابل مصدر البيانات الأساسي (مثل استخدام SELECT TOP 1 في SQL).

يرى:

نصائح أخرى

في الحياة الحقيقية، إذا كنت تستخدم Orm مثل LinQ-To-SQL

  • إذا قمت بإنشاء IQueryable, ، ثم قد يتم تحويل الاستعلام إلى SQL وتشغيلها على خادم قاعدة البيانات
  • إذا قمت بإنشاء IEnumerable, ، ثم سيتم سحب جميع الصفوف في الذاكرة ككائنات قبل تشغيل الاستعلام.

في كلتا الحالتين إذا كنت لا تتصل ToList() أو ToArray() ثم سيتم تنفيذ الاستعلام في كل مرة يتم استخدامه، لذلك، قل، لديك IQueryable ويمكنك ملء 4 صناديق قائمة منه، ثم سيتم تشغيل الاستعلام مقابل قاعدة البيانات 4 مرات.

أيضا إذا قمت بتمديد استفسارك:

q.Select(x.name = "a").ToList()

ثم مع an. IQueryable سوف تحتوي SQL التي تم إنشاؤها where name = "a", ، ولكن مع IEnumerable سيتم سحب العديد من الأدوار مرة أخرى من قاعدة البيانات، ثم x.name = "a" تحقق سيتم القيام به بواسطة .NET.

"الاختلاف الأساسي هو أن أساليب التمديد المحددة بالنسبة لمقايير تأخذ كائنات التعبير بدلا من كائنات Funcery، مما يعني أن المفوض الذي يتلقاه هو شجرة تعبير بدلا من طريقة لاستدعاءها. Ienumerable رائعا للعمل مع مجموعات في الذاكرة، ولكن IQueryable يسمح للحصول على مصدر بيانات عن بعد، مثل قاعدة بيانات أو خدمة ويب "

مصدر: هنا

ienumerable. ienumerable هو أفضل مناسبة للعمل مع مجموعة في الذاكرة. لا يتحرك iEnumerable بين العناصر، إنه يتوجه مجموعة فقط.

Iqueryable.أفضل دعاوى IQueryable لمصدر البيانات عن بعد، مثل قاعدة بيانات أو خدمة ويب. IQueryable هي ميزة قوية للغاية تتيح مجموعة متنوعة من سيناريوهات التنفيذ المؤجلة المثيرة للاهتمام (مثل الاستعلامات القائمة على الترحيل والتكوين).

لذلك عندما تضطر إلى التكرار ببساطة من خلال مجموعة الذاكرة، استخدم iEnumperable، إذا كنت بحاجة إلى القيام بأي معالجة مع مجموعة مثل DataSet ومصادر البيانات الأخرى، استخدم IQueryable

الفرق الرئيسي هو أن ienumerable سوف تعداد جميع عناصرها طوال الوقت، في حين أن iqueryable سوف تعداد العناصر، أو حتى القيام بأشياء أخرى، بناء على استعلام. الاستعلام هو تعبير (تمثيل بيانات من كود .NET)، والتي يجب أن تستكشف iqueryprovider / تفسير / ترجمة / أي شيء من أجل توليد النتائج.

وجود تعبير الاستعلام يعطي مزايتين.

الميزة الأولى هي الأمثل. نظرا لأن المعدلات مثل "حيث" يتم تضمينها في تعبير الاستعلام، فإن IQueryProvider يمكن أن ينطبق على التحسينات المستحيلة بشكل خلاف ذلك. بدلا من إرجاع جميع العناصر، قم بإلقاء معظمها بسبب وجود بند "حيث"، يمكن للمزود استخدام جدول التجزئة لتحديد موقع العناصر مع مفتاح معين.

الميزة الثانية هي المرونة. نظرا لأن التعبيرات هي هياكل بيانات مستكشفة، يمكنك القيام بأشياء مثل تسلسل الاستعلام وإرسالها إلى جهاز بعيد (على سبيل المثال Linq-to-sql).

iquerable هو نفسه Ienumerable ولكنه يوفر أيضا وظائف إضافية لتنفيذ استعلام مخصص مع LinQ. هنا الوصف على MSDN: http://msdn.microsoft.com/en-us/library/system.linq.iquerable.aspx.

تم العثور على ienumerable أولا في مساحة الاسم. إذا كنت تستخدم iEnaryerable عند الاستعلام عن البيانات من مجموعات في الذاكرة مثل المجموعة، وكافة الصفيف وما إلى ذلك، وعند الاستعلام عن البيانات من الذاكرة الخارجية (مثل قاعدة البيانات البعيدة، الخدمة)، فإنك تستخدم IQueryable. لأنه أثناء الاستعلام عن البيانات من قاعدة البيانات، قم بالتنفيذ iEnumeerable SELECT استعلام على جانب الخادم، وتحميل البيانات في الذاكرة على جانب العميل ثم تصفية البيانات. وبالتالي فإن المزيد من العمل ويصبح بطيئا. أثناء الاستعلام عن البيانات من قاعدة البيانات، قم بتنفيذ IQueryable Select SELECT QUERY على جانب الخادم مع جميع المرشحات. وبالتالي يفعل العمل أقل ويصبح بسرعة.

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