PDA

View Full Version : تولید خودکار UserName (مثل شماره دانشجویی)



skflower
دوشنبه 03 اسفند 1388, 03:38 صبح
سلام دوستان. من دارم یه پروژه مینویسم که در هنگام عضویت، UserName بصورت خودکار تولید میشه و یه شماره ی 7 رقمی هستش (مثل شماره دانشجویی). بدین ترتیب که اولین شماره 1000000 و دومین 1000001 و سومین 1000002 و الی آخر.
الگوریتم من تا حالا این بوده که اومدم تعداد یوزر ها رو از طریق GetAllUsers() بدست اووردم و اون رو بعلاوه 1000000 کردم و این شده Username جدیدم.
حالا یه اشکال اساسی داره و اون هم اینکه فرض کنیم از سه تا یورزی که تا الان ساختیم وسطی رو حذف کنیم. یعنی یورزهای ما بشن 1000000 و 1000002. حالا یورز جدید که میخواد ساخته بشه نام کاربری میشه همون 1000002 که تکراریه و به خطا میخوریم. از طرفی میخوام که جای خالی یوزری که حذف شده پر بشه. یعنی اگه کسی بخواد عضو بشه نام کاربریش بشه 1000001 که قبلاً حذف شده ولی شماره های قبل و بعدش موجودن.
الگوریتمی که به ذهنم اوم اینه که یکی یکی بیام یوزرها رو با یه حلقه تکرار بخونم و بفهمم. اما این در صورتی ممکنه که یوزر ها به ترتیب باشن.
حالا هم میخواستم ببینم که GetAllUsers ترتیبی که میده بر اساس چیه و هم اگه کسی الگوریتمی دیگه به ذهنش میرسه لطف کنه و بگه.

skflower
دوشنبه 03 اسفند 1388, 13:24 عصر
خودم فهمیدم. ظاهراً که GetAllUsers() بر اساس تاریخ ساخت برمیگردونه. که البته میتونه بر اساس ID هم باشه. چرا که IDها پشت سر هم هستند.

mehdi.mousavi
دوشنبه 03 اسفند 1388, 14:20 عصر
خودم فهمیدم. ظاهراً که GetAllUsers() بر اساس تاریخ ساخت برمیگردونه. که البته میتونه بر اساس ID هم باشه. چرا که IDها پشت سر هم هستند.

سلام.
این متود در واقع aspnet_Membership_GetAllUsers رو فراخوانی میکنه. اگر به این Stored Procedure نگاه کنید، متوجه می شید که رکوردها بر اساس UserName مرتب میشن و بر میگردن. من بخشی از این SP رو اینجا میذارم تا خودتون ببینید:

SELECT u.UserName, m.Email, m.PasswordQuestion, m.Comment, m.IsApproved,
m.CreateDate,
m.LastLoginDate,
u.LastActivityDate,
m.LastPasswordChangedDate,
u.UserId, m.IsLockedOut,
m.LastLockoutDate
FROM dbo.aspnet_Membership m, dbo.aspnet_Users u, #PageIndexForUsers p
WHERE u.UserId = p.UserId AND u.UserId = m.UserId AND
p.IndexId >= @PageLowerBound AND p.IndexId <= @PageUpperBound
ORDER BY u.UserName


موفق باشید.

skflower
دوشنبه 03 اسفند 1388, 14:24 عصر
آقا الان شما دو باره که توی دو تا پست مختلف به من جواب میدید. خداییش خیلی سطح بالا میگید. من تازه از دلفی به سمت C# کوچ کردم. اوقدرها هم حرفه ای نیستم که این چیزا رو راحت بفهمم. میشه یکم بیشتر توضیح بدید.
آیا الگوریتمی برای سوالی که در بالا پرسیدم میتونید پیشنهاد بدید؟

mehdi.mousavi
دوشنبه 03 اسفند 1388, 16:41 عصر
آقا الان شما دو باره که توی دو تا پست مختلف به من جواب میدید. خداییش خیلی سطح بالا میگید. من تازه از دلفی به سمت C#‎ کوچ کردم. اوقدرها هم حرفه ای نیستم که این چیزا رو راحت بفهمم. میشه یکم بیشتر توضیح بدید. آیا الگوریتمی برای سوالی که در بالا پرسیدم میتونید پیشنهاد بدید؟

سلام.
واقعیت اینه که من از این کاری که شما انجام داده اید خوشم نمیاد. منظورم، تولید کردن اینطور ID هاست... از اون بدتر اینه که شما میخواهید ID ای که به هر دلیلی حذف میشه رو بعدا به فرد جدیدی اختصاص بدید. این کار دیگه به نظر من اصلا درست نیست. ID تولید شده و به هر دلیلی دیگه قابل استفاده نیست، دیگه نباید برگردید و همون ID رو برای فرد دیگه ای مجددا استفاده کنید. اگر اینکارو انجام بدید، اونوقت دو نفر، تو دو بازه زمانی متفاوت، هر دو دارای یک ID بودن و ... در نتیجه ID دیگه Unique نخواهد بود چون بیش از یک نفر میتونن ادعا کنن که فلان ID متعلق به اونهاست و شما هم معیاری برای تشخیص درست یا نادرست بودن این ادعا ندارید.

در هر حال، من پیشنهاد دیگه ای دارم. اگر این ID ها همواره با عددی غیر از صفر شروع میشه، اونوقت میتونید این ID ها رو IDENTITY تعیین کنید تا خودشون از عدد دلخواهی که شما تعیین میکنید هنگام INSERT شدن در جدول، یکی یکی افزایش پیدا کنن. بعبارت دیگه، اگر الان ID پانزده توی بانک وجود داره، SQL SERVER خودش برای نفر بعد، هنگام INSERT میتونه ID ی 16 رو در نظر بگیره... اینطوری دیگه شما نیازی نیست تا الگوریتمی برای تعیین ID بنویسید و البته، این اعداد تولید شده نیز لزوما پشت سر هم نخواهند بود. به بیان دیگه، ممکنه بنا به دلائلی SQL SERVER تشخیص بده که الان میتونه ID ی 17 رو به کاربر جدید اختصاص بده، نه ID شانزده رو! در نتیجه، ID 16 هرگز استفاده نخواهد شد.

به هر حال، اگر اصرار دارید که کاری رو که توضیح دادید انجام بدید، بهتون پیشنهاد میکنم با نوشتن یک Stored Procedure در SQL Server اینکارو انجام بدید. بدین ترتیب که ابتدا رکوردها رو SORT کنید، سپس اونها رو بهمراه یک IDENTITY جدید که از کوچکترین عدد ایجاد شده در لیست شروع میشه، در یک جدول موقت نگهداری کنید. اولین رکوردی که در ستون IDENTITY وجود داره اما در ستون ID های شما وجود نداره، میشه ID ای که شما میتونید ازش استفاده کنید.

به بیان دیگه، فرض کنید 4 تا رکورد تو بانک داریم با ID های 7، 3، 5، 6
حالا میاییم اینا رو مرتب میکنیم، کوچک به بزرگ: 3,5,6,7
بعد اینا رو به ترتیب در جدول جدیدی که IDENTITY اش از 3 شروع میشه، قرار میدیم. پس یک جدول داریم با دو ستون:

ID IDENTITY
3 3
5 4
6 5
7 6


حالا توی این جدول موقت، اولین Row ای که دو ستونش با هم برابر نیستن، میشه ID ای که شما باید استفاده کنید. به این ترتیب، Row دوم از جدول فوق، داره نشون میده ID ای که باید استفاده کنید 4 هستش...

موفق باشید.

پاورقی: اولش خواستم روش استفاده از CURSOR رو براتون توضیح بدم، اما خوب، CURSOR ها خیلی کند هستن و ... این روش رو هم همینکه شروع به نوشتن کردم به ذهنم خطور کرد، بنابراین حتما قبل از پیاده سازی آزمایش کنید که حالت استثنایی در اون وجود نداشته باشه.

skflower
دوشنبه 03 اسفند 1388, 16:50 عصر
دوست عزیز تمامی فرمایشات شما درسته. اما فکر میکنم منظورم رو درست نرسوندم. من ID نمیخوام تولید کنم. آی دی ها در فیلد دیگه از جدول هستن. من فقط دارم UserName تولید میکنم. که تو پروژم اسمش رو گذاشتم کد شناسایی.
در ضمن واقعاً ممنونم که این همه وقت گذاشتید و جواب دادید.
یک دنیا ممنونم.

mehdi.mousavi
دوشنبه 03 اسفند 1388, 17:00 عصر
دوست عزیز تمامی فرمایشات شما درسته. اما فکر میکنم منظورم رو درست نرسوندم. من ID نمیخوام تولید کنم. آی دی ها در فیلد دیگه از جدول هستن. من فقط دارم UserName تولید میکنم. که تو پروژم اسمش رو گذاشتم کد شناسایی.
در ضمن واقعاً ممنونم که این همه وقت گذاشتید و جواب دادید.
یک دنیا ممنونم.

تو پست قبلی، منظورم از ID همون UserName بود. اگر متوجه نشدید، در اولین فرصت براتون توضیح میدم.

موفق باشید.

پاورقی: الان فرصت نمیکنم اینکارو کنم.