IQueryable
লিনকিউ এর প্রসঙ্গে কী ব্যবহার ?
এটি সম্প্রসারণ পদ্ধতি বা অন্য কোনও উদ্দেশ্যে বিকাশের জন্য ব্যবহৃত হয়?
IQueryable
লিনকিউ এর প্রসঙ্গে কী ব্যবহার ?
এটি সম্প্রসারণ পদ্ধতি বা অন্য কোনও উদ্দেশ্যে বিকাশের জন্য ব্যবহৃত হয়?
উত্তর:
মার্ক গ্র্যাভেলের উত্তরটি সম্পূর্ণ সম্পূর্ণ, তবে আমি ভেবেছিলাম ব্যবহারকারীর দৃষ্টিকোণ থেকে আমি এ সম্পর্কে কিছু যুক্ত করব, ...
ব্যবহারকারীর দৃষ্টিকোণ থেকে মূল পার্থক্য হ'ল আপনি যখন ব্যবহার করবেন use IQueryable<T>
(এমন কোনও সরবরাহকারীর সাথে যা জিনিসকে সঠিকভাবে সমর্থন করে) আপনি প্রচুর সংস্থান সংরক্ষণ করতে পারেন।
উদাহরণস্বরূপ, আপনি যদি অনেকগুলি ওআরএম সিস্টেমের সাথে কোনও দূরবর্তী ডাটাবেসের বিরুদ্ধে কাজ করছেন তবে আপনার কাছে দুটি উপায়ে একটি টেবিল থেকে ডেটা আনার বিকল্প রয়েছে, একটি যা প্রত্যাবর্তন করে IEnumerable<T>
এবং একটি যা প্রত্যাবর্তন করে IQueryable<T>
। বলুন, উদাহরণস্বরূপ, আপনার কাছে একটি পণ্য সারণী রয়েছে এবং আপনি যে সমস্ত পণ্যগুলির দাম> $ 25 হয় তার সমস্ত পেতে চান।
যদি তুমি করো:
IEnumerable<Product> products = myORM.GetProducts();
var productsOver25 = products.Where(p => p.Cost >= 25.00);
এখানে কী ঘটে, ডাটাবেস হ'ল সমস্ত পণ্য লোড হয় এবং সেগুলি আপনার কম্পিউটারে সরবরাহ করে। আপনার প্রোগ্রামটি তখন ডেটা ফিল্টার করে। সংক্ষেপে, ডাটাবেসটি একটি করে SELECT * FROM Products
, এবং আপনাকে প্রতিটি পণ্য প্রদান করে।
অন্যদিকে সঠিক IQueryable<T>
সরবরাহকারীর সাহায্যে আপনি এটি করতে পারেন:
IQueryable<Product> products = myORM.GetQueryableProducts();
var productsOver25 = products.Where(p => p.Cost >= 25.00);
কোডটি দেখতে একই রকম, তবে এখানে পার্থক্য হ'ল কার্যকর করা এসকিউএল হবে SELECT * FROM Products WHERE Cost >= 25
।
বিকাশকারী হিসাবে আপনার পিওভি থেকে, এটি দেখতে একই রকম। তবে, পারফরম্যান্সের দিক থেকে আপনি কেবলমাত্র 20,000 এর পরিবর্তে নেটওয়ার্ক জুড়ে 2 টি রেকর্ড ফিরিয়ে দিতে পারেন ....
IQueryable<Product>
করবে যা কোনও ফেরত দেয় - এটি আপনার ওআরএম বা সংগ্রহশালা ইত্যাদির জন্য নির্দিষ্ট হবে
foreach
, বা কল করুন ToList()
), আপনি আসলে ডিবিতে আঘাত করবেন না।
সংক্ষেপে এটির কাজটি একটি অনুরূপ IEnumerable<T>
ডেটা উত্সকে উপস্থাপন করতে - বিভিন্ন লিংক পদ্ধতি (অন Queryable
) Expression
প্রতিনিধিদের চেয়ে গাছ ব্যবহার করে কোয়েরিটি তৈরি করা আরও নির্দিষ্ট হতে পারে (এটি কীEnumerable
।
আপনার পছন্দসই লিনকিউ সরবরাহকারী দ্বারা অভিব্যক্তি গাছগুলি পরিদর্শন করা যেতে পারে এবং একটি আসল জিজ্ঞাসায় পরিণত হতে পারে - যদিও এটি নিজের মধ্যে একটি কালো শিল্প।
এটি সত্যিই নীচে নেমে এসেছে ElementType
, Expression
এবং Provider
- তবে বাস্তবে আপনাকে ব্যবহারকারী হিসাবে খুব কমই এ সম্পর্কে যত্ন নেওয়া প্রয়োজন । কেবলমাত্র একটি লিনকিউ প্রয়োগকারীকে বিশ্রী বিবরণগুলি জানতে হবে।
মন্তব্যসমূহ; উদাহরণস্বরূপ আপনি কী চান তা আমি নিশ্চিত নই, তবে লিনকুই-টু এসকিউএল বিবেচনা করুন; এখানে কেন্দ্রীয় অবজেক্টটি একটি DataContext
, যা আমাদের ডাটাবেস-মোড়কে উপস্থাপন করে। এটিতে সাধারণত প্রতি টেবিলের সম্পত্তি থাকে (উদাহরণস্বরূপ Customers
), এবং একটি টেবিল সরঞ্জাম রয়েছে IQueryable<Customer>
। তবে আমরা এগুলি সরাসরি ব্যবহার করি না; বিবেচনা:
using(var ctx = new MyDataContext()) {
var qry = from cust in ctx.Customers
where cust.Region == "North"
select new { cust.Id, cust.Name };
foreach(var row in qry) {
Console.WriteLine("{0}: {1}", row.Id, row.Name);
}
}
এটি হয়ে যায় (সি # সংকলক দ্বারা):
var qry = ctx.Customers.Where(cust => cust.Region == "North")
.Select(cust => new { cust.Id, cust.Name });
যা আবার ব্যাখ্যা করা হয়েছে (সি # সংকলক দ্বারা) হিসাবে:
var qry = Queryable.Select(
Queryable.Where(
ctx.Customers,
cust => cust.Region == "North"),
cust => new { cust.Id, cust.Name });
গুরুত্বপূর্ণভাবে, Queryable
টেক অফ এক্সপ্রেশন ট্রিগুলিতে স্থিতিশীল পদ্ধতিগুলি , যা নিয়মিত আইএল না করে কোনও বস্তুর মডেলটিতে সংকলিত হয়। উদাহরণস্বরূপ - কেবল "কোথায়" তাকান, এটি আমাদের সাথে তুলনা করার মতো কিছু দেয়:
var cust = Expression.Parameter(typeof(Customer), "cust");
var lambda = Expression.Lambda<Func<Customer,bool>>(
Expression.Equal(
Expression.Property(cust, "Region"),
Expression.Constant("North")
), cust);
... Queryable.Where(ctx.Customers, lambda) ...
সংকলকটি আমাদের জন্য অনেক কিছু করেনি? এই অবজেক্টের মডেলটি ছিন্ন-বিচ্ছিন্ন হতে পারে, এর অর্থ কী তা পরীক্ষা করাতে পারে এবং টিএসকিউএল জেনারেটর দ্বারা আবার একসাথে রাখা যেতে পারে - এরকম কিছু দেওয়া:
SELECT c.Id, c.Name
FROM [dbo].[Customer] c
WHERE c.Region = 'North'
(স্ট্রিংটি প্যারামিটার হিসাবে শেষ হতে পারে; আমি মনে করতে পারি না)
যদি আমরা কেবল একটি প্রতিনিধি ব্যবহার করে থাকি তবে এর কিছুই সম্ভব হবে না। আর এই বিন্দু Queryable
/ IQueryable<T>
: এটা মত প্রকাশের গাছ ব্যবহার করার জন্য এন্ট্রি দফা প্রদান করে।
এগুলি সবই জটিল, সুতরাং এটি খুব ভাল কাজ যে সংকলকটি এটি আমাদের জন্য সুন্দর এবং সহজ করে তুলেছে।
আরও তথ্যের জন্য, " ডিপথ ইন সি # " বা " লিনকিউ ইন অ্যাকশন " দেখুন, উভয়ই এই বিষয়গুলির কভারেজ সরবরাহ করে।
যদিও রিড Copsey এবং মার্ক Gravell ইতিমধ্যে সম্পর্কে বর্ণনা IQueryable
(এবং IEnumerable
) যথেষ্ট, MI উপর একটি ছোট উদাহরণ প্রদানের মাধ্যমে একটু বেশি এখানে যোগ করতে চান IQueryable
এবংIEnumerable
অনেক ব্যবহারকারী এটি চেয়েছিলেন বলে
উদাহরণ : আমি ডাটাবেসে দুটি টেবিল তৈরি করেছি
CREATE TABLE [dbo].[Employee]([PersonId] [int] NOT NULL PRIMARY KEY,[Gender] [nchar](1) NOT NULL)
CREATE TABLE [dbo].[Person]([PersonId] [int] NOT NULL PRIMARY KEY,[FirstName] [nvarchar](50) NOT NULL,[LastName] [nvarchar](50) NOT NULL)
PersonId
সারণীর প্রাথমিক কী ( ) Employee
হ'ল ফোরজিন কী (personid
)Person
এরপরে আমি আমার অ্যাপ্লিকেশনটিতে অ্যাডো নেট নেট সত্তা মডেল যুক্ত করেছি এবং সেবার নীচে পরিষেবা শ্রেণি তৈরি করব
public class SomeServiceClass
{
public IQueryable<Employee> GetEmployeeAndPersonDetailIQueryable(IEnumerable<int> employeesToCollect)
{
DemoIQueryableEntities db = new DemoIQueryableEntities();
var allDetails = from Employee e in db.Employees
join Person p in db.People on e.PersonId equals p.PersonId
where employeesToCollect.Contains(e.PersonId)
select e;
return allDetails;
}
public IEnumerable<Employee> GetEmployeeAndPersonDetailIEnumerable(IEnumerable<int> employeesToCollect)
{
DemoIQueryableEntities db = new DemoIQueryableEntities();
var allDetails = from Employee e in db.Employees
join Person p in db.People on e.PersonId equals p.PersonId
where employeesToCollect.Contains(e.PersonId)
select e;
return allDetails;
}
}
তাদের একই লিঙ্ক রয়েছে। এটি program.cs
নীচে সংজ্ঞায়িত হিসাবে বলা হয়
class Program
{
static void Main(string[] args)
{
SomeServiceClass s= new SomeServiceClass();
var employeesToCollect= new []{0,1,2,3};
//IQueryable execution part
var IQueryableList = s.GetEmployeeAndPersonDetailIQueryable(employeesToCollect).Where(i => i.Gender=="M");
foreach (var emp in IQueryableList)
{
System.Console.WriteLine("ID:{0}, EName:{1},Gender:{2}", emp.PersonId, emp.Person.FirstName, emp.Gender);
}
System.Console.WriteLine("IQueryable contain {0} row in result set", IQueryableList.Count());
//IEnumerable execution part
var IEnumerableList = s.GetEmployeeAndPersonDetailIEnumerable(employeesToCollect).Where(i => i.Gender == "M");
foreach (var emp in IEnumerableList)
{
System.Console.WriteLine("ID:{0}, EName:{1},Gender:{2}", emp.PersonId, emp.Person.FirstName, emp.Gender);
}
System.Console.WriteLine("IEnumerable contain {0} row in result set", IEnumerableList.Count());
Console.ReadKey();
}
}
স্পষ্টত উভয় জন্য আউটপুট একই
ID:1, EName:Ken,Gender:M
ID:3, EName:Roberto,Gender:M
IQueryable contain 2 row in result set
ID:1, EName:Ken,Gender:M
ID:3, EName:Roberto,Gender:M
IEnumerable contain 2 row in result set
সুতরাং প্রশ্নটি কি / কোথায় পার্থক্য আছে? মনে হচ্ছে না কোন পার্থক্য আছে ঠিক? সত্যিই !!
আসুন এই সময়কালে সত্তা ফ্রেমওয়ার্ক 5 দ্বারা উত্পাদিত এবং সম্পাদিত এসকিএল ক্যোয়ারীগুলি একবার দেখে নেওয়া যাক
আইকিউয়েরেবল এক্সিকিউশন অংশ
--IQueryableQuery1
SELECT
[Extent1].[PersonId] AS [PersonId],
[Extent1].[Gender] AS [Gender]
FROM [dbo].[Employee] AS [Extent1]
WHERE ([Extent1].[PersonId] IN (0,1,2,3)) AND (N'M' = [Extent1].[Gender])
--IQueryableQuery2
SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT(1) AS [A1]
FROM [dbo].[Employee] AS [Extent1]
WHERE ([Extent1].[PersonId] IN (0,1,2,3)) AND (N'M' = [Extent1].[Gender])
) AS [GroupBy1]
আইকনামেবল এক্সিকিউশন অংশ
--IEnumerableQuery1
SELECT
[Extent1].[PersonId] AS [PersonId],
[Extent1].[Gender] AS [Gender]
FROM [dbo].[Employee] AS [Extent1]
WHERE [Extent1].[PersonId] IN (0,1,2,3)
--IEnumerableQuery2
SELECT
[Extent1].[PersonId] AS [PersonId],
[Extent1].[Gender] AS [Gender]
FROM [dbo].[Employee] AS [Extent1]
WHERE [Extent1].[PersonId] IN (0,1,2,3)
উভয় নির্বাহ অংশের জন্য সাধারণ স্ক্রিপ্ট
/* these two query will execute for both IQueryable or IEnumerable to get details from Person table
Ignore these two queries here because it has nothing to do with IQueryable vs IEnumerable
--ICommonQuery1
exec sp_executesql N'SELECT
[Extent1].[PersonId] AS [PersonId],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName]
FROM [dbo].[Person] AS [Extent1]
WHERE [Extent1].[PersonId] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=1
--ICommonQuery2
exec sp_executesql N'SELECT
[Extent1].[PersonId] AS [PersonId],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName]
FROM [dbo].[Person] AS [Extent1]
WHERE [Extent1].[PersonId] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=3
*/
সুতরাং আপনার এখন কয়েকটি প্রশ্ন রয়েছে, আমাকে সেগুলি অনুমান করতে দিন এবং তাদের উত্তর দেওয়ার চেষ্টা করুন
একই ফলাফলের জন্য কেন বিভিন্ন স্ক্রিপ্ট তৈরি করা হয়?
এখানে কিছু পয়েন্ট খুঁজে পেতে দিন,
সমস্ত প্রশ্নের একটি সাধারণ অংশ রয়েছে
WHERE [Extent1].[PersonId] IN (0,1,2,3)
কেন? কারণ উভয় ফাংশন IQueryable<Employee> GetEmployeeAndPersonDetailIQueryable
এবং
IEnumerable<Employee> GetEmployeeAndPersonDetailIEnumerable
এর SomeServiceClass
লিনক ক্যোয়ারিতে একটি সাধারণ লাইন থাকে
where employeesToCollect.Contains(e.PersonId)
AND (N'M' = [Extent1].[Gender])
পার্টটি IEnumerable
এক্সিকিউশন অংশে অনুপস্থিত কেন , উভয় ফাংশন কলিংয়ে আমরা Where(i => i.Gender == "M") in
প্রোগ্রামের সিএস ব্যবহার করেছি Than
এখন আমরা সেই বিন্দুতে এসেছি যেখানে পার্থক্য এসেছিল
IQueryable
এবং এর মধ্যেIEnumerable
সত্তা ফ্রেমওয়ার্ক যখন একটি করে IQueryable
পদ্ধতিটি , এটি পদ্ধতির অভ্যন্তরে লিঙ্কযুক্ত বিবৃতিটি চেয়েছিল এবং ফলাফলের উপর আরও লিনাকের অভিব্যক্তি সংজ্ঞায়িত করা হয়েছে কিনা তা অনুসন্ধান করার চেষ্টা করে, ফলস্বরূপ ফলাফল আনার প্রয়োজন না হওয়া পর্যন্ত এটি নির্ধারিত সমস্ত লিনক কোয়েরি সংগ্রহ করে এবং আরও যথাযথ স্কয়ার তৈরি করে কার্যকর করতে জিজ্ঞাসা।
এটি প্রচুর উপকার সরবরাহ করে যেমন,
এখানে যেমন উদাহরণস্বরূপ, এসকিউএল সার্ভার আইকুয়েরেবল এক্সিকিউটিশনের পরে মাত্র দুটি সারি প্রয়োগ করে ফিরে এসেছিল - তবে তিনটি সারি ফিরিয়েছে কেন আইক্যুয়্যারি ক্যোয়ারির জন্য?
IEnumerable
পদ্ধতির ক্ষেত্রে , সত্তা কাঠামোটি পদ্ধতির অভ্যন্তরে লিঙ্কযুক্ত বিবৃতি গ্রহণ করে এবং যখন ফলাফল আনার দরকার হয় তখন স্কিল কোয়েরি তৈরি করে। এটিতে স্কিল কোয়েরি তৈরির জন্য বিশ্রামের লিঙ্ক অংশ অন্তর্ভুক্ত নয়। এখানে যেমন কলামে স্কেল সার্ভারে কোনও ফিল্টারিং করা হয় না gender
।
কিন্তু ফলাফল কি একই? কারণ 'এসকিউএল সার্ভার থেকে ফলাফল পুনরুদ্ধার করার পরে আইনুনামেবল ফল প্রয়োগের পর্যায়ে আরও ফিল্টার করে
সুতরাং, কেউ কি চয়ন করা উচিত? আমি ব্যক্তিগতভাবে ফাংশন ফলাফল সংজ্ঞায়িত করতে পছন্দ করি IQueryable<T>
কারণ এতে প্রচুর সুবিধা রয়েছেIEnumerable
, আপনি দু'একটি বেশি আইকিউয়েরেবল ফাংশনগুলিতে যোগ দিতে পারেন, যা এসকিউএল সার্ভারে আরও নির্দিষ্ট স্ক্রিপ্ট তৈরি করে।
এখানে উদাহরণস্বরূপ আপনি দেখতে পাচ্ছেন IQueryable Query(IQueryableQuery2)
যে একটি আরও নির্দিষ্ট স্ক্রিপ্ট তৈরি করা হয়েছে IEnumerable query(IEnumerableQuery2)
যা আমার দৃষ্টিতে অনেক বেশি গ্রহণযোগ্য।
এটি আরও লাইনটি আরও জিজ্ঞাসা করার অনুমতি দেয়। যদি এটি কোনও পরিষেবার সীমানার বাইরে ছিল, তবে এই আইকিউয়েরেবল অবজেক্টটির ব্যবহারকারীকে এর সাথে আরও কিছু করার অনুমতি দেওয়া হবে।
উদাহরণস্বরূপ আপনি যদি নিবারনেটের সাথে অলস লোডিং ব্যবহার করে থাকেন তবে প্রয়োজনে / যখন প্রয়োজন হয় গ্রাফটি লোড হতে পারে।