PDA

View Full Version : شماره فاکتور | نحوه‌ی ایجاد یک شماره‌ی منحصر بفرد و غیر تکراری مرتب! | LINQ



hadimtn
شنبه 14 شهریور 1394, 04:10 صبح
سلام.
چه جوری می‌تونم یه شماره‌ی منحصر بفرد تولید کنم و هر بار که نیاز بود یک شماره بالاتر از اون رو وارد پایگاه داده کنم!
یه چیزی شبیه identity می‌خوام، اما فرقش اینکه که identity برای هر سطر یک شماره اختصاص میده ولی من نیاز دارم تا برای چندین سطر داده‌ی تکراری وارد کنم!

نظر بنده اینه که یه متغیره سراسری با مقدار اولیه تعریف کنم:
Int64 FactorNumber = 1000;
در صورتی که جدول مربوطه خالی بود، مقدار متغیر سراسری وارد پایگاه داده بشه
و در غیر اینصورت جستجو برای بزرگترین شماره فاکتور درج شده انجام بشه و شماره‌ی بعدی طبق اون ساخته بشه! (که ایراد این روش هزینه‌ی جستجو در پایگاه داده است!)
لطفاً راهنمایی کنید و در صورت امکان Query مربوطه رو هم بنویسید.

Mahmoud.Afrad
شنبه 14 شهریور 1394, 18:55 عصر
اگر برای درج در دو جدول (برای ثبت فاکتور) نیاز داری ، کافیه بعد از ثبت در جدول اول ، مقدار ID رو بخونی و برای ثبت در جدول دوم استفاده کنی.

hadimtn
یک شنبه 15 شهریور 1394, 00:44 صبح
اگر برای درج در دو جدول (برای ثبت فاکتور) نیاز داری ، کافیه بعد از ثبت در جدول اول ، مقدار ID رو بخونی و برای ثبت در جدول دوم استفاده کنی.
این روشی که توضیح دادم مناسبه؟!
در ضمن متوجه منظورتون نشدم!
بنده یک جدول فاکتور دارم که یک فیلد FactorNumber داره، ردیف‌هایی که شماره ی تکراری دارن یک فاکتور هستن!

Mahmoud.Afrad
یک شنبه 15 شهریور 1394, 02:56 صبح
ستونهای جدول؟؟

hadimtn
دوشنبه 16 شهریور 1394, 02:58 صبح
اگر برای درج در دو جدول (برای ثبت فاکتور) نیاز داری ، کافیه بعد از ثبت در جدول اول ، مقدار ID رو بخونی و برای ثبت در جدول دوم استفاده کنی.

فکر کنم متوجه منظورتون شدم؛ اول اطلاعات مربوط به ثبت فاکتور در جدول مربوطه ثبت بشه:

135050

بعد از ثبت شماره‌ی فاکتور که خاصیت Identity داره، بقیه‌ی جاها استفاده بشه، که در اینجا در جدول مربوط به اجناس فروخته شده است استفاده میشه:

135051

درسته؟!

Mahmoud.Afrad
دوشنبه 16 شهریور 1394, 04:53 صبح
بله، دقیقا. البته در یک تراکنش درج رکوردها رو انجام بدید تا در صورت ناموفق بودن بتونید rollback کنید.

hadimtn
دوشنبه 16 شهریور 1394, 06:15 صبح
بله، دقیقا.
به دلیل اینکه کاربر داخل فرمی که داره کالاها رو انتخاب میکنه، شماره فاکتور رو هم میبینه، به این شیوه عمل کردم:

LINQDataContext db = new LINQDataContext();
var FactorNumber = (from f in db.FactorTables
select f.FactorNumber);
if (FactorNumber.Count() > 0)
{
Int32 tempNumber = (Convert.ToInt32(FactorNumber.Max())) + 1;
txt_FactorNumber.Text = tempNumber.ToString();
}
else if (FactorNumber.Count() == 0)
{
txt_FactorNumber.Text = "1000";
}

ولی به نظرم قسمت else رو اصولی ننوشتم و اصلاً جالب نیست!
چه جوری میشه مستقیم با identity کار کرد؟!یعنی بنویسم که:
identity ای که اگه سطری وارد بشه بهش تخصیص میدی رو بریز تو جعبه‌ی متن شماره فاکتور!


البته در یک تراکنش درج رکوردها رو انجام بدید تا در صورت ناموفق بودن بتونید rollback کنید.
دیگه دارین پیچیده‌ش میکنین من نمی‌دونم چه جوری باید rollback کنم!

Mahmoud.Afrad
دوشنبه 16 شهریور 1394, 21:00 عصر
در صورتی که ستون کلید اصلی Identity هست و توسط پایگاه داده مقداردهی میشه، برای بدست آوردن آیدی قبل از درج (آیدی که قراره درج بشه) استفاده از متد Max اشتباست. چون: فرض کنید یک رکورد ثبت کردید که آیدی این رکورد 10 شده . سپس به دلیلی این رکورد رو حذف میکنید. خب حالا آخرین آیدی 9 هست. اگر یکی بهش اضافه کنید میشه 10. شما انتظار دارید در صورت ثبت رکورد جدید آیدی اون 10 باشه ولی 11 خواهد بود.

برای اینکه متوجه آیدی رکوردی که هنوز ثبت نشده بشید، میتونید از فانکشن IDENT_CURRENT در کوئری sql استفاده کنید.
به اینصورت(مطابق کد خودت):

private void GetNextFactorNumber()
{
LINQDataContext db = new LINQDataContext();

string tableName = GetTableName(db.FactorTables);
string strCommand = string.Format("select cast(IDENT_CURRENT('{0}') as int) ", tableName);
int nextFactorNumber = db.ExecuteQuery<int>(strCommand).FirstOrDefault();

txt_FactorNumber.Text = nextFactorNumber;
}


public string GetTableName<TEntity>(Table<TEntity> myTable) where TEntity : class
{
string tableName = null;
Type type = typeof (TEntity);
object[] temp = type.GetCustomAttributes(typeof (System.Data.Linq.Mapping.TableAttribute), true);
if (temp.Length <= 0) return null;
var tableAttribute = temp[0] as System.Data.Linq.Mapping.TableAttribute;
if (tableAttribute == null) return null;
tableName = tableAttribute.Name;
return tableName;
}



برای تراکنش هم لینک زیر رو ببین
http://barnamenevis.org/showthread.php?385939-transeaction-%D9%87%D8%A7%DB%8C-linq-to-sql&p=1710480&viewfull=1#post1710480