আমার যখন শর্ত রয়েছে তখন লিনক থেকে এসকিউএল ব্যবহার করে এলোমেলো সারিটি পুনরুদ্ধার করার সর্বোত্তম (এবং দ্রুততম) উপায় কী, উদাহরণস্বরূপ কিছু ক্ষেত্র সত্য হতে হবে?
আমার যখন শর্ত রয়েছে তখন লিনক থেকে এসকিউএল ব্যবহার করে এলোমেলো সারিটি পুনরুদ্ধার করার সর্বোত্তম (এবং দ্রুততম) উপায় কী, উদাহরণস্বরূপ কিছু ক্ষেত্র সত্য হতে হবে?
উত্তর:
আপনি এটি একটি নকল ইউডিএফ ব্যবহার করে ডাটাবেসে করতে পারেন; আংশিক শ্রেণিতে, ডেটা প্রসঙ্গে একটি পদ্ধতি যুক্ত করুন:
partial class MyDataContext {
[Function(Name="NEWID", IsComposable=true)]
public Guid Random()
{ // to prove not used by our C# code...
throw new NotImplementedException();
}
}
তারপরে ঠিক order by ctx.Random()
; এটি এসকিউএল-সার্ভার সৌজন্যে এলোমেলোভাবে অর্ডার করবে NEWID()
। অর্থাত
var cust = (from row in ctx.Customers
where row.IsActive // your filter
orderby ctx.Random()
select row).FirstOrDefault();
মনে রাখবেন এটি কেবলমাত্র ছোট থেকে মাঝের আকারের টেবিলের জন্য উপযুক্ত; বিশাল টেবিলগুলির জন্য, এটি সার্ভারে একটি কার্যকারিতা প্রভাব ফেলবে এবং সারিগুলির সংখ্যা ( Count
) সন্ধান করতে এটি আরও দক্ষ হবে , তারপরে এলোমেলোভাবে একটি বেছে নিন ( Skip/First
)।
গণনা পদ্ধতির জন্য:
var qry = from row in ctx.Customers
where row.IsActive
select row;
int count = qry.Count(); // 1st round-trip
int index = new Random().Next(count);
Customer cust = qry.Skip(index).FirstOrDefault(); // 2nd round-trip
সত্তা ফ্রেমওয়ার্কের জন্য অন্য একটি নমুনা:
var customers = db.Customers
.Where(c => c.IsActive)
.OrderBy(c => Guid.NewGuid())
.FirstOrDefault();
এটি লিনকিউ থেকে এসকিউএল নিয়ে কাজ করে না। OrderBy
কেবল বাদ করা হচ্ছে।
সম্পাদনা: আমি কেবলমাত্র এটি লক্ষ্য করেছি এটি এসকিউএল থেকে লিনিক, অবজেক্টে লিনকিউ নয়। আপনার জন্য এটি করতে ডাটাবেস পেতে মার্কের কোডটি ব্যবহার করুন। আমি এই উত্তরটি অবজেক্টগুলিতে লিনকুইয়ের আগ্রহের পয়েন্ট হিসাবে এখানে রেখেছি।
আশ্চর্যজনকভাবে যথেষ্ট, আপনার আসলে গণনা পাওয়ার দরকার নেই। তবে আপনাকে গণনা না পাওয়া পর্যন্ত প্রতিটি উপাদান আনতে হবে।
আপনি যা করতে পারেন তা হ'ল "বর্তমান" মান এবং বর্তমান গণনা সম্পর্কে ধারণা রাখা। আপনি যখন পরবর্তী মানটি আনবেন তখন একটি এলোমেলো নম্বর নিন এবং "বর্তমান "টিকে" নতুন "সাথে 1 / n এর সম্ভাব্যতার সাথে প্রতিস্থাপন করুন যেখানে n গণনা।
সুতরাং আপনি যখন প্রথম মানটি পড়েন, আপনি সর্বদা এটি "বর্তমান" মানটি তৈরি করেন। আপনি যখন দ্বিতীয় মানটি পড়েন, আপনি এটি করতে পারেন যে বর্তমান মান (সম্ভাব্যতা 1/2)। আপনি যখন তৃতীয় মানটি পড়েন তখন আপনি এটি করতে পারেন যে বর্তমান মান (সম্ভাব্যতা ১/৩) ইত্যাদি data
একটি শর্ত সহ এটি প্রয়োগ করতে, শর্তটি পূরণ করে না এমন কিছু উপেক্ষা করুন। এটির সবচেয়ে সহজ উপায় হ'ল প্রথমে একটি ক্লজ প্রয়োগ করে শুরু করার জন্য কেবল "ম্যাচিং" ক্রমটি বিবেচনা করা।
এখানে একটি দ্রুত বাস্তবায়ন। আমি মনে করি এটি ঠিক আছে ...
public static T RandomElement<T>(this IEnumerable<T> source,
Random rng)
{
T current = default(T);
int count = 0;
foreach (T element in source)
{
count++;
if (rng.Next(count) == 0)
{
current = element;
}
}
if (count == 0)
{
throw new InvalidOperationException("Sequence was empty");
}
return current;
}
current
হবে সবসময় প্রথম উপাদান সেট করা। দ্বিতীয় পুনরাবৃত্তিতে, একটি 50% পরিবর্তন রয়েছে যে এটি দ্বিতীয় উপাদানটিতে সেট করা হবে। তৃতীয় পুনরাবৃত্তিতে, এটির তৃতীয় উপাদানটিতে সেট করার 33% সুযোগ রয়েছে। ব্রেক স্টেটমেন্ট যুক্ত করার অর্থ হ'ল আপনি প্রথম উপাদানটি পড়ার পরে সর্বদা প্রস্থান করবেন এবং একেবারেই এলোমেলো নয় making
দক্ষতার সাথে অর্জন করার একটি উপায় হ'ল আপনার ডেটাতে একটি কলাম যুক্ত করা Shuffle
যা এলোমেলো ইনট দ্বারা জনবহুল হয় (প্রতিটি রেকর্ড তৈরি হওয়ার সাথে সাথে)।
এলোমেলো ক্রমে টেবিলটি অ্যাক্সেস করতে আংশিক কোয়েরিটি হ'ল ...
Random random = new Random();
int seed = random.Next();
result = result.OrderBy(s => (~(s.Shuffle & seed)) & (s.Shuffle | seed)); // ^ seed);
এটি ডাটাবেসে একটি এক্সওর অপারেশন করে এবং সেই এক্সওরটির ফলাফল অনুসারে অর্ডার দেয়।
সুবিধাদি:-
এটি আমার হোম অটোমেশন সিস্টেমটি প্লেলিস্টগুলি এলোমেলো করে জানাতে ব্যবহার করে। এটি প্রতিদিন একটি নতুন বীজ বাছাই করে দিনের সময় একটি সামঞ্জস্যপূর্ণ অর্ডার দেয় (সহজ বিরতি / পুনরায় জীবনযাত্রার সক্ষমতার অনুমতি দেয়) তবে প্রতিটি নতুন দিন প্রতিটি প্লেলিস্টে একটি নতুন চেহারা।
result = result.OrderBy(s => s.Shuffle ^ seed);
(যেমন ~, এবং এবং অপারেটরগুলির মাধ্যমে এক্সওআর বাস্তবায়ন করার প্রয়োজন নেই)।
আপনি যদি var count = 16
টেবিল থেকে উদাহরণস্বরূপ এলোমেলো সারি পেতে চান তবে আপনি লিখতে পারেন
var rows = Table.OrderBy(t => Guid.NewGuid())
.Take(count);
এখানে আমি ইএফ ব্যবহার করেছি, এবং সারণীটি একটি ডিবিসেট
List<string> lst = new List<string>();
lst.Add("Apple");
lst.Add("Guva");
lst.Add("Graps");
lst.Add("PineApple");
lst.Add("Orange");
lst.Add("Mango");
var customers = lst.OrderBy(c => Guid.NewGuid()).FirstOrDefault();
ব্যাখ্যা: গাইড সন্নিবেশ করা (যা এলোমেলো) অর্ডারবাই সহ অর্ডারটি এলোমেলো হবে।
এখান থেকে অল্প সংখ্যক কয়েকটি র্যান্ডম পেজ কীভাবে পাবেন তা ভাবতে ভাবতে এখানে এসেছিলেন, সুতরাং প্রতিটি ব্যবহারকারীর কিছু আলাদা র্যান্ডম 3 পৃষ্ঠা পাওয়া যায়।
এটি আমার চূড়ান্ত সমাধান, শেয়ারপয়েন্ট ২০১০-এর পৃষ্ঠাগুলির তালিকার বিরুদ্ধে লিনকুইয়ের সাথে খোঁজখবর নিচ্ছেন। এটি ভিজ্যুয়াল বেসিকের মধ্যে রয়েছে, দুঃখিত: পি
Dim Aleatorio As New Random()
Dim Paginas = From a As SPListItem In Sitio.RootWeb.Lists("Páginas") Order By Aleatorio.Next Take 3
সম্ভবত প্রচুর ফলাফল জিজ্ঞাসা করার আগে কিছুটা প্রোফাইলিং করা উচিত, তবে এটি আমার উদ্দেশ্যটির জন্য উপযুক্ত
DataTable
এর বিপরীতে আমার কাছে এলোমেলো ফাংশন ক্যোয়ারী রয়েছে :
var result = (from result in dt.AsEnumerable()
order by Guid.NewGuid()
select result).Take(3);
নীচের উদাহরণটি উত্সটিকে একটি গণনা পুনরুদ্ধার করতে কল করবে এবং তারপরে 0 এবং n এর মধ্যে একটি সংখ্যার সাথে উত্সটিতে একটি স্কিপ এক্সপ্রেশন প্রয়োগ করবে। দ্বিতীয় পদ্ধতিটি এলোমেলো বস্তু (যা মেমরিতে সমস্ত কিছু অর্ডার করবে) ব্যবহার করে আদেশ প্রয়োগ করবে এবং পদ্ধতি কলটিতে পাস নম্বরটি নির্বাচন করবে।
public static class IEnumerable
{
static Random rng = new Random((int)DateTime.Now.Ticks);
public static T RandomElement<T>(this IEnumerable<T> source)
{
T current = default(T);
int c = source.Count();
int r = rng.Next(c);
current = source.Skip(r).First();
return current;
}
public static IEnumerable<T> RandomElements<T>(this IEnumerable<T> source, int number)
{
return source.OrderBy(r => rng.Next()).Take(number);
}
}
আমি এলোমেলো সংবাদ এবং এর কাজ সূক্ষ্ম গ্রহণের জন্য এই পদ্ধতিটি ব্যবহার করি;)
public string LoadRandomNews(int maxNews)
{
string temp = "";
using (var db = new DataClassesDataContext())
{
var newsCount = (from p in db.Tbl_DynamicContents
where p.TimeFoPublish.Value.Date <= DateTime.Now
select p).Count();
int i;
if (newsCount < maxNews)
i = newsCount;
else i = maxNews;
var r = new Random();
var lastNumber = new List<int>();
for (; i > 0; i--)
{
int currentNumber = r.Next(0, newsCount);
if (!lastNumber.Contains(currentNumber))
{ lastNumber.Add(currentNumber); }
else
{
while (true)
{
currentNumber = r.Next(0, newsCount);
if (!lastNumber.Contains(currentNumber))
{
lastNumber.Add(currentNumber);
break;
}
}
}
if (currentNumber == newsCount)
currentNumber--;
var news = (from p in db.Tbl_DynamicContents
orderby p.ID descending
where p.TimeFoPublish.Value.Date <= DateTime.Now
select p).Skip(currentNumber).Take(1).Single();
temp +=
string.Format("<div class=\"divRandomNews\"><img src=\"files/1364193007_news.png\" class=\"randomNewsImg\" />" +
"<a class=\"randomNews\" href=\"News.aspx?id={0}\" target=\"_blank\">{1}</a></div>",
news.ID, news.Title);
}
}
return temp;
}
var cust = (from c in ctx.CUSTOMERs.ToList() select c).OrderBy(x => x.Guid.NewGuid()).Taket(2);
এলোমেলো 2 সারি নির্বাচন করুন
মার্ক গ্র্যাভেলের দ্রবণে যোগ করতে। যদি আপনি নিজেই ড্যাটাকনটেক্সট ক্লাসের সাথে কাজ করছেন না (কারণ আপনি এটি পরীক্ষার উদ্দেশ্যে কোনওভাবে উদাহরণস্বরূপ ডেটাঅন্টেক্সটকে নকল করে), আপনি সংজ্ঞায়িত ইউডিএফ সরাসরি ব্যবহার করতে পারবেন না: এটি এসকিউএলে সংকলিত হবে না কারণ আপনি এটি কোনওতে ব্যবহার করছেন না আপনার প্রকৃত ডেটা প্রসঙ্গ শ্রেণীর সাবক্লাস বা আংশিক বর্গ।
এই সমস্যাটির সমাধানের জন্য হ'ল আপনার প্রক্সিটিতে একটি র্যান্ডমাইজ ফাংশন তৈরি করা, আপনি যে প্রশ্নটি এলোমেলো করে রাখতে চান তা দিয়ে এটি খাওয়ানো:
public class DataContextProxy : IDataContext
{
private readonly DataContext _context;
public DataContextProxy(DataContext context)
{
_context = context;
}
// Snipped irrelevant code
public IOrderedQueryable<T> Randomize<T>(IQueryable<T> query)
{
return query.OrderBy(x => _context.Random());
}
}
আপনি আপনার কোডটিতে এটি কীভাবে ব্যবহার করবেন তা এখানে রয়েছে:
var query = _dc.Repository<SomeEntity>();
query = _dc.Randomize(query);
সম্পূর্ণ হওয়ার জন্য, এটি FAKE ডেটাঅন্টেক্সটে (যা মেমরি সত্তায় ব্যবহার করে) এটি প্রয়োগ করতে হয়:
public IOrderedQueryable<T> Randomize<T>(IQueryable<T> query)
{
return query.OrderBy(x => Guid.NewGuid());
}