سلام.
در قدم اول برای جدولتون یک کلید در نظر بگیرید.
برای رکوردهای رندوم غیر تکراری بهترین راه اینه که در سمت sql رکوردهای غیر تکراری رو برگردونید چون سرعت کار در قیاس با انجام همین کار در سمت سی شارپ بسیار بیشتر هستش.
من هر دو روش رو میگم شما هر مدل که خواستی استفاده کن :
کوئری در سمت Sql :
select top(10) * from TblQuestion
order by NEWID()
و اگر بخواید همین کار رو در سمت سی شارپ انجام بدید، ناچارید ابتدا تمام رکوردها رو از سمت Sql به محیط ویژوال انتقال بدید و فرضا درون یک دیتاتیبل بریزیدش.
حالا نیاز به یکی شی مثل لیست باکس دارید تا شماره رکورد های رندوم غیرتکراری رو درونش نگهداری کنید. اصول کار به این شکل خواهد بود که هر بار یک عدد رندوم تولید میشه واین عدد با عدد موجود در لیست مقایسه میشه، در صورتیکه برابر نبود بعنوان یک عدد جدید (رکورد جدید) به لیست باکس اضافه می شود. کل این مراحل درون یک حلقه while صورت می گیره و تا زمانیکه آیتم های این لیست به تعداد سوالات مد نظر کاربر نرسیده این عمل مرتبا تکرار میشه تا رکوردهای رندوم غیر تکراری بدست بیان. همونطور که می بینید، روند کار بسیار پر هزینه و دشوارتر است نسبت به روش اول.
در کد زیر منظور از dt همون دیتاتیبل هست که شامل لیست همه رکوردهای جدول هستش و MyListResult هم همون لیست باکسی هست که شماره رکوردهای رندوم غیرتکراری رو درون خودش نگهداری میکنه.
while (MyListResult.Items.Count < Convert.ToInt32(TxtQuestionNumber.Text.Trim()))
{
Random rand = new Random();
num = rand.Next(Convert.ToInt32(dt.Rows[0][0]), Convert.ToInt32(dt.Rows[dt.Rows.Count - 1][0]) + 1);
//
for (int i = 0; i < dt.Rows.Count ; i++)
{
if (num == Convert.ToInt32(dt.Rows[i][0]))
{
i = dt.Rows.Count;
if (MyListResult.Items.Count == 0)
MyListResult.Items.Add(num);
else if (!MyListResult.Items.Contains(num))
MyListResult.Items.Add(num);
}
}
}
موفق باشید.