উত্তর:
আপনি এটি সম্পর্কে যেভাবে ভাবছেন তার নিরিখে এটি আপনার মাথা ঘুরিয়ে দেওয়া দরকার। প্রযোজ্য ব্যবহারকারীর অধিকারের পূর্বনির্ধারিত সংকলনে বর্তমান আইটেমটির ব্যবহারকারীর অধিকারগুলি অনুসন্ধান করতে "ইন" না করার পরিবর্তে আপনি ব্যবহারকারীর অধিকারের একটি পূর্বনির্ধারিত সেট জিজ্ঞাসা করছেন যদি এতে বর্তমান আইটেমটির প্রযোজ্য মান থাকে। আপনি নেট থেকে নিয়মিত তালিকায় কোনও আইটেমটি দেখতে পাবেন ঠিক ঠিক একই পথে।
লিনকিউ ব্যবহার করে এটি করার দুটি উপায় রয়েছে, একটি কোয়েরি সিনট্যাক্স এবং অন্যটি পদ্ধতি সিনট্যাক্স ব্যবহার করে। মূলত, এগুলি হ'ল এবং আপনার পছন্দের উপর নির্ভর করে বিনিময়যোগ্যভাবে ব্যবহার করা যেতে পারে:
অনুসন্ধান সিনট্যাক্স:
var selected = from u in users
where new[] { "Admin", "User", "Limited" }.Contains(u.User_Rights)
select u
foreach(user u in selected)
{
//Do your stuff on each selected user;
}
পদ্ধতি সিনট্যাক্স:
var selected = users.Where(u => new[] { "Admin", "User", "Limited" }.Contains(u.User_Rights));
foreach(user u in selected)
{
//Do stuff on each selected user;
}
এই উদাহরণে আমার ব্যক্তিগত পছন্দটি পদ্ধতি সিনট্যাক্স হতে পারে কারণ ভেরিয়েবলটি বরাদ্দের পরিবর্তে আমি বেনামে এইরকম কল করে ভবিষ্যদ্বাণীটি করতে পারি:
foreach(User u in users.Where(u => new [] { "Admin", "User", "Limited" }.Contains(u.User_Rights)))
{
//Do stuff on each selected user;
}
কৃত্রিমভাবে এটি আরও জটিল দেখায় এবং ল্যাম্বডা এক্সপ্রেশন বা প্রতিনিধিদের ধারণাটি বুঝতে হবে যা ঘটছে তা সত্যিই খুঁজে বের করার জন্য, তবে আপনি দেখতে পাচ্ছেন যে এই কোডটি ন্যায্য পরিমাণে ঘনীভূত করে।
এটি সব আপনার কোডিং শৈলীতে এবং পছন্দটিতে নেমে আসে - আমার তিনটি উদাহরণ একই জিনিসটি কিছুটা ভিন্নভাবে করে।
বিকল্প উপায় এমনকি লিনকিউ ব্যবহার করে না, আপনি "ফাইন্ডএল" এর সাথে "যেখানে" প্রতিস্থাপন করে একই পদ্ধতি সিনট্যাক্স ব্যবহার করতে পারেন এবং একই ফলাফল পাবেন, যা নেট .০.০ এও কাজ করবে:
foreach(User u in users.FindAll(u => new [] { "Admin", "User", "Limited" }.Contains(u.User_Rights)))
{
//Do stuff on each selected user;
}
এটি আপনার উদ্দেশ্যটি যথেষ্ট should এটি দুটি সংগ্রহের তুলনা করে এবং চেকগুলি তুলনা করে যদি একটি সংগ্রহে অন্য সংগ্রহের সাথে মানগুলির সাথে মিল রয়েছে
fea_Features.Where(s => selectedFeatures.Contains(s.feaId))
আপনি যদি VS2008 / .NET 3.5 ব্যবহার করেন তবে অ্যালেক্স জেমসের টিপ # 8 দেখুন: http://blogs.msdn.com/alexj/archive/2009/03/26/tip-8-writing-where-in-style -queries-ব্যবহার-linq টু entities.aspx
অন্যথায় কেবল অ্যারে ব্যবহার করুন ont
আমি এই প্রসঙ্গে ইনার জয়েনের পক্ষে যাব। আমি যদি এতে ব্যবহার করে থাকি তবে এটি মাত্র একটি ম্যাচ আছে তা সত্ত্বেও এটি 6 বার পুনরাবৃত্তি হবে।
var desiredNames = new[] { "Pankaj", "Garg" };
var people = new[]
{
new { FirstName="Pankaj", Surname="Garg" },
new { FirstName="Marc", Surname="Gravell" },
new { FirstName="Jeff", Surname="Atwood" }
};
var records = (from p in people join filtered in desiredNames on p.FirstName equals filtered select p.FirstName).ToList();
ধরুন আমার কাছে দুটি তালিকার অবজেক্ট রয়েছে।
List 1 List 2
1 12
2 7
3 8
4 98
5 9
6 10
7 6
কন্টেনস ব্যবহার করে, এটি তালিকা 2 এর প্রতিটি তালিকা 1 আইটেম অনুসন্ধান করবে যার অর্থ পুনরাবৃত্তি 49 বার ঘটবে !!!
আমি একটি এসকিউএল-ইন-জাতীয় জিনিসটির সাথেও কাজ করার চেষ্টা করেছি - একটি সত্তা ডেটা মডেলের বিরুদ্ধে জিজ্ঞাসা করছি । আমার পদ্ধতির একটি বড় OR- এক্সপ্রেশন রচনা করার জন্য একটি স্ট্রিং নির্মাতা। এটি ভয়াবহভাবে কুৎসিত, তবে আমি এখনই একমাত্র উপায় হওয়ার ভয় করি।
এখন ভাল, এটি দেখতে দেখতে:
Queue<Guid> productIds = new Queue<Guid>(Products.Select(p => p.Key));
if(productIds.Count > 0)
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("{0}.ProductId = Guid\'{1}\'", entities.Products.Name, productIds.Dequeue());
while(productIds.Count > 0)
{
sb.AppendFormat(" OR {0}.ProductId = Guid\'{1}\'",
entities.Products.Name, productIds.Dequeue());
}
}
এই প্রসঙ্গে জিইউইউডির সাথে কাজ করা : আপনি উপরের মতো দেখতে পাচ্ছেন, কোয়েরি স্ট্রিংয়ের খণ্ডগুলিতে স্বয়ংক্রিয়ভাবে জিইউইডি-র আগে "জিইউডি" শব্দটি রয়েছে। আপনি যদি এটি যোগ না করেন তবে ObjectQuery<T>.Where
নিম্নলিখিত ব্যতিক্রম ছোঁড়ে:
'Edm.Guid' এবং 'Edm.String' আর্গুমেন্টের ধরণগুলি এই অপারেশনের জন্য বেমানান।, সমান অভিব্যক্তির নিকটে, লাইন 6, কলাম 14।
এটি এমএসডিএন ফোরামে পাওয়া গেছে, এটি মনে রাখতে সহায়ক হতে পারে।
ম্যাথিয়াস
... NET এবং সত্তা ফ্রেমওয়ার্কের পরবর্তী সংস্করণটির জন্য অপেক্ষা করছি, যখন সবকিছু ভাল হয়। :)
বেনআলাবাস্টারের উত্তরের একটি বিকল্প পদ্ধতি
প্রথমত, আপনি কোয়েরিটি আবার লিখতে পারেন:
var matches = from Users in people
where Users.User_Rights == "Admin" ||
Users.User_Rights == "Users" ||
Users.User_Rights == "Limited"
select Users;
অবশ্যই এটি আরও 'শব্দযুক্ত' এবং লেখার জন্য একটি ব্যথা তবে এটি একই রকম কাজ করে।
সুতরাং আমাদের যদি এমন কিছু ইউটিলিটি পদ্ধতি থাকে যা এই ধরণের লিনকিউ এক্সপ্রেশন তৈরি করতে সহজ করে তোলে আমরা ব্যবসায় থাকব।
জায়গায় একটি ইউটিলিটি পদ্ধতিতে আপনি এই জাতীয় কিছু লিখতে পারেন:
var matches = ctx.People.Where(
BuildOrExpression<People, string>(
p => p.User_Rights, names
)
);
এটি এমন একটি অভিব্যক্তি তৈরি করে যা এর মতো একই প্রভাব ফেলে:
var matches = from p in ctx.People
where names.Contains(p.User_Rights)
select p;
তবে এটি আরও গুরুত্বপূর্ণভাবে কাজ করে। নেট 3.5 এসপি 1 এর বিপরীতে।
এখানে নদীর গভীরতানির্ণয় কার্যটি এটি সম্ভব করে তোলে:
public static Expression<Func<TElement, bool>> BuildOrExpression<TElement, TValue>(
Expression<Func<TElement, TValue>> valueSelector,
IEnumerable<TValue> values
)
{
if (null == valueSelector)
throw new ArgumentNullException("valueSelector");
if (null == values)
throw new ArgumentNullException("values");
ParameterExpression p = valueSelector.Parameters.Single();
if (!values.Any())
return e => false;
var equals = values.Select(value =>
(Expression)Expression.Equal(
valueSelector.Body,
Expression.Constant(
value,
typeof(TValue)
)
)
);
var body = equals.Aggregate<Expression>(
(accumulate, equal) => Expression.Or(accumulate, equal)
);
return Expression.Lambda<Func<TElement, bool>>(body, p);
}
আমি এই পদ্ধতিটি ব্যাখ্যা করার চেষ্টা করতে যাচ্ছি না, অন্যটি বলার অপেক্ষা রাখে না যে এটি মূলত ভ্যালু সিলেক্টর (অর্থাত্ পি => পি। সূত্রের বিধেয়
বাস্তব উদাহরণ:
var trackList = Model.TrackingHistory.GroupBy(x => x.ShipmentStatusId).Select(x => x.Last()).Reverse();
List<int> done_step1 = new List<int>() {2,3,4,5,6,7,8,9,10,11,14,18,21,22,23,24,25,26 };
bool isExists = trackList.Where(x => done_step1.Contains(x.ShipmentStatusId.Value)).FirstOrDefault() != null;
সিরিয়াসলি? আপনি লোকেরা কখনও ব্যবহার করেন নি
where (t.MyTableId == 1 || t.MyTableId == 2 || t.MyTableId == 3)
Checks = NumValues * NumRows
। কারণ এটি একটি এম * এন টাইপ গণনা, যদি হয় তবে তা যদি ছোট হয় তবে প্রতিটি প্রয়োজনীয় চেক সম্পাদনের সময়ও কম হবে। আমি সীমাবদ্ধতাটি যোগ করেছি তাই সিজেএম 30305 কীভাবে একটি পরীক্ষার পরিবেশ নির্ধারণ করতে পারে যেখানে তার সমাধানটি কেন দুর্বল তা দেখানো হবে।
where new[] { 1, 2, 3 }.Contains(x)
তখন তুলনা কম হয় where (x == 1 || x == 2 || x == 3)
?