আমরা একটি লগ ভিউয়ারে কাজ করছি। ব্যবহারের ক্ষেত্রে ব্যবহারকারী, তীব্রতা ইত্যাদি দ্বারা ফিল্টার করার অপশন থাকবে q বেকার দিনগুলিতে আমি কোয়েরি স্ট্রিংয়ে যোগ করব, তবে আমি লিনক দিয়ে এটি করতে চাই। আমি কীভাবে শর্তাধীন যেখানে ক্লজগুলি যুক্ত করতে পারি?
উত্তর:
আপনি যদি নির্দিষ্ট মানদণ্ড পাস হলেই ফিল্টার করতে চান তবে এই জাতীয় কিছু করুন
var logs = from log in context.Logs
select log;
if (filterBySeverity)
logs = logs.Where(p => p.Severity == severity);
if (filterByUser)
logs = logs.Where(p => p.User == user);
এইভাবে করা আপনার এক্সপ্রেশন ট্রিটি আপনি যা চান ঠিক তেমন হতে দেবে। এই ভাবে তৈরি এসকিউএল হ'ল আপনার প্রয়োজনটি ঠিক তেমন হবে এবং এর চেয়ে কম কিছুই নয়।
LINQ to Entities does not recognize the method 'System.String get_Item(System.String)' method, and this method cannot be translated into a store expression.
আপনার যদি কোনও তালিকা / অ্যারেতে বেস ফিল্টার করতে হয় তবে নিম্নলিখিতগুলি ব্যবহার করুন:
public List<Data> GetData(List<string> Numbers, List<string> Letters)
{
if (Numbers == null)
Numbers = new List<string>();
if (Letters == null)
Letters = new List<string>();
var q = from d in database.table
where (Numbers.Count == 0 || Numbers.Contains(d.Number))
where (Letters.Count == 0 || Letters.Contains(d.Letter))
select new Data
{
Number = d.Number,
Letter = d.Letter,
};
return q.ToList();
}
আমি ড্যারেনের অনুরূপ উত্তর ব্যবহার করে শেষ করেছি, তবে একটি আইকিউয়েরেবল ইন্টারফেস সহ:
IQueryable<Log> matches = m_Locator.Logs;
// Users filter
if (usersFilter)
matches = matches.Where(l => l.UserName == comboBoxUsers.Text);
// Severity filter
if (severityFilter)
matches = matches.Where(l => l.Severity == comboBoxSeverity.Text);
Logs = (from log in matches
orderby log.EventTime descending
select log).ToList();
এটি ডেটাবেস হিট করার আগে ক্যোয়ারী তৈরি করে। কমান্ডটি চলবে না। টোললিস্ট () শেষে।
শর্তসাপেক্ষ লিনাকের কথা এলে আমি ফিল্টার এবং পাইপ প্যাটার্নটি খুব পছন্দ করি।
http://blog.wekeroad.com/mvc-storefront/mvcstore-part-3/
মূলত আপনি প্রতিটি ফিল্টার কেসের জন্য একটি এক্সটেনশন পদ্ধতি তৈরি করেন যা আইকোয়ারিযোগ্য এবং একটি পরামিতি নেয়।
public static IQueryable<Type> HasID(this IQueryable<Type> query, long? id)
{
return id.HasValue ? query.Where(o => i.ID.Equals(id.Value)) : query;
}
আমি একটি প্রসারিত পদ্ধতির সাহায্যে এটি সমাধান করেছিলাম যাতে একটি সাবলীল অভিব্যক্তির মাঝখানে শর্তসাপেক্ষে LINQ সক্ষম করা যায়। এটি if
বিবৃতি সহ অভিব্যক্তি ভাঙ্গার প্রয়োজনীয়তা সরিয়ে দেয় ।
.If()
এক্সটেনশন পদ্ধতি:
public static IQueryable<TSource> If<TSource>(
this IQueryable<TSource> source,
bool condition,
Func<IQueryable<TSource>, IQueryable<TSource>> branch)
{
return condition ? branch(source) : source;
}
এটি আপনাকে এটি করতে দেয়:
return context.Logs
.If(filterBySeverity, q => q.Where(p => p.Severity == severity))
.If(filterByUser, q => q.Where(p => p.User == user))
.ToList();
এখানে এমন একটি IEnumerable<T>
সংস্করণ রয়েছে যা বেশিরভাগ অন্যান্য লিনকিউ এক্সপ্রেশন পরিচালনা করবে:
public static IEnumerable<TSource> If<TSource>(
this IEnumerable<TSource> source,
bool condition,
Func<IEnumerable<TSource>, IEnumerable<TSource>> branch)
{
return condition ? branch(source) : source;
}
আরেকটি বিকল্প হ'ল এখানে আলোচনা করা প্রিডিকেট বিল্ডারের মতো কিছু ব্যবহার করা । এটি আপনাকে নীচের মত কোড লিখতে দেয়:
var newKids = Product.ContainsInDescription ("BlackBerry", "iPhone");
var classics = Product.ContainsInDescription ("Nokia", "Ericsson")
.And (Product.IsSelling());
var query = from p in Data.Products.Where (newKids.Or (classics))
select p;
নোট করুন যে আমি লিনক 2 এসকিউএল এর সাথে কাজ করতে পেরেছি। সত্তা ফ্রেমওয়ার্ক এক্সপ্রেশন প্রয়োগ করে না nআনভোক করুন, যা এই পদ্ধতির কাজ করার জন্য প্রয়োজনীয়। আমি এই সমস্যা সম্পর্কে এখানে একটি প্রশ্ন আছে ।
এটা করছি:
bool lastNameSearch = true/false; // depending if they want to search by last name,
where
বিবৃতিতে এই হচ্ছে :
where (lastNameSearch && name.LastNameSearch == "smith")
এর অর্থ হ'ল চূড়ান্ত ক্যোয়ারী তৈরি করা হয়, যদি lastNameSearch
হয় false
তবে কোয়েরিটি সর্বশেষ নাম অনুসন্ধানের জন্য কোনও এসকিউএলকে পুরোপুরি বাদ দেবে।
এটি সবচেয়ে সুন্দর জিনিস নয় তবে আপনি ল্যাম্বডা এক্সপ্রেশনটি ব্যবহার করতে পারেন এবং আপনার শর্তগুলি বিকল্পভাবে পাস করতে পারেন। টিএসকিউএলে আমি প্যারামিটারগুলি alচ্ছিক করতে নিম্নলিখিত অনেকগুলি করি:
যেখানে ক্ষেত্র = @ ফিল্ডওয়ার বা @ ফিল্ডভারটি নিখুঁত
আপনি নীচের ল্যাম্বডা (প্রমাণীকরণ যাচাইয়ের উদাহরণ) দিয়ে একই স্টাইলের সদৃশ করতে পারেন:
MyDataContext db = নতুন MyDataContext ();
অকার্যকর রানকুয়েরি (স্ট্রিং প্যারাম 1, স্ট্রিং প্যারাম 2, ইনট? প্যারাম 3)
Func চেকউজার = ব্যবহারকারী =>
((প্যারাম 1. দৈর্ঘ্য> 0)? ইউজার.পারাম 1 == পরম 1: 1 == 1) &&
((প্যারাম 2. দৈর্ঘ্য> 0)? ইউজার.পারাম 2 == পরম 2: 1 == 1) &&
((প্যারাম 3! = নাল)? ইউজার.প্যারাম ৩ == প্যারাম 3: 1 == 1);
ব্যবহারকারী পাওয়া গেছে ইউজার = ডিবি। ব্যবহারকারীরা.সিংল ওআরডিফল্ট (চেক ব্যবহারকারী);
}
আমার সম্প্রতি অনুরূপ প্রয়োজনীয়তা ছিল এবং শেষ পর্যন্ত তিনি এমএসডিএন-তে এটি পেয়ে গেলেন। ভিজ্যুয়াল স্টুডিও ২০০ for এর জন্য সিএসআরপ নমুনা
ডাউনলোডের ডায়নামিককুয়ের নমুনায় অন্তর্ভুক্ত ক্লাসগুলি আপনাকে নিম্নলিখিত বিন্যাসে রানটাইম সময়ে গতিশীল ক্যোয়ারী তৈরি করতে দেয়:
var query =
db.Customers.
Where("City = @0 and Orders.Count >= @1", "London", 10).
OrderBy("CompanyName").
Select("new(CompanyName as Name, Phone)");
এটি ব্যবহার করে আপনি রানটাইম সময়ে গতিশীলভাবে ক্যোয়ারী স্ট্রিং তৈরি করতে পারেন এবং এটি কোথায় () পদ্ধতিতে পাস করতে পারেন:
string dynamicQueryString = "City = \"London\" and Order.Count >= 10";
var q = from c in db.Customers.Where(queryString, null)
orderby c.CompanyName
select c;
কেবল সি # এর && অপারেটরটি ব্যবহার করুন:
var items = dc.Users.Where(l => l.Date == DateTime.Today && l.Severity == "Critical")
সম্পাদনা: আহ, আরও মনোযোগ সহকারে পড়া দরকার। আপনি কীভাবে শর্তসাপেক্ষে অতিরিক্ত ধারাগুলি যুক্ত করবেন তা জানতে চেয়েছিলেন । সেক্ষেত্রে আমার কোনও ধারণা নেই। :) আমি সম্ভবত যা করছিলাম তা হল বেশ কয়েকটি ক্যোয়ারী প্রস্তুত করা, এবং আমার প্রয়োজনীয়তার উপর নির্ভর করে ডানটি কার্যকর করা।
আপনি একটি বাহ্যিক পদ্ধতি ব্যবহার করতে পারেন:
var results =
from rec in GetSomeRecs()
where ConditionalCheck(rec)
select rec;
...
bool ConditionalCheck( typeofRec input ) {
...
}
এটি কাজ করবে তবে এক্সপ্রেশন ট্রিগুলিতে ভাঙা যাবে না, যার অর্থ লিনক থেকে এসকিউএল প্রতিটি রেকর্ডের বিপরীতে চেক কোডটি চালাবে।
বিকল্পভাবে:
var results =
from rec in GetSomeRecs()
where
(!filterBySeverity || rec.Severity == severity) &&
(!filterByUser|| rec.User == user)
select rec;
এটি এক্সপ্রেশন ট্রিগুলিতে কাজ করতে পারে যার অর্থ লিনাক থেকে এসকিউএল অনুকূলিত হবে।
ঠিক আছে, আমি যা ভেবেছিলাম আপনি ফিল্টার শর্তগুলি পূর্বাভাসের জেনেরিক তালিকায় রাখতে পারেন:
var list = new List<string> { "me", "you", "meyou", "mow" };
var predicates = new List<Predicate<string>>();
predicates.Add(i => i.Contains("me"));
predicates.Add(i => i.EndsWith("w"));
var results = new List<string>();
foreach (var p in predicates)
results.AddRange(from i in list where p.Invoke(i) select i);
এর ফলে "আমি", "মাইউ" এবং "কাঁচা" থাকা একটি তালিকার ফলস্বরূপ।
আপনি পূর্বাভাসগুলি সম্পূর্ণ ভিন্ন ফাংশনে ভবিষ্যদ্বাণীগুলির সাথে পূর্বাভাসটি করে যা অপরিবর্তিত সমস্ত ওআরএসকে অনুকূল করে তুলতে পারে।