PDA

View Full Version : مشکل در insert دو جدول در EF



amir3321
دوشنبه 14 فروردین 1391, 23:56 عصر
با سلام خدمت استادان عزیز
من یک عمل INSERT در entity framework بوسیله یک تابع می خواهم انجام بدهم که در آن ابتدایک جدول با pk با قابلیت identity یک رکورد ثبت می شود وسپس با گرفتن id در جدول دوم یک رکورد دیگر ثبت می شود
مشکل در اینجا این است که هنگام رخ دادن خطا و کنترل آن و بازگشت دوباره به تابع id دو بار عمل increment انجام شده است کد تابع رو اینجا قرار می دهم تا راهنمایی فرمایید .


public static int adduser
(string username, Boolean typeuser, int groupid, string pass, Boolean active
, string fname, string lname, string fax, string email, GNREntities user)
{

using (var transactionScope = new TransactionScope())
{
try
{
// user.SaveChanges(SaveOptions.None);
// addperson(active, fname, lname, fax, email, user);
// addpersonid = user.persons.Max(s => s.id)+1;
addperson(active, fname, lname, fax, email,user);
// persons person = new persons();

// person.fname = fname;
// person.fax = fax;
// person.lname = lname;
// person.email = email;
// person.active = active;

// user.persons.AddObject(person);
// user.SaveChanges();
sysuser user1 = new sysuser();
user1.active = active;
user1.username = username;
user1.groupid = groupid;
user1.pass = pass;
user1.personid = addpersonid;// auser.persons.Max(s => s.id);
user1.typeuser = typeuser;

user.sysusers.AddObject(user1);
user.SaveChanges();
transactionScope.Complete();
user.AcceptAllChanges();
return 0;
}
catch (Exception exp)
{

if (exp.InnerException.Message.Contains("unique") || exp.InnerException.Message.Contains("duplicate"))
{
user = null;
return -1;
}
else
clsmain.except = exp;
return -9;
}
}

}



private void adduser()
{
usersdata = null;
usersdata = new GNREntities();
chkinputdata();
int id;
if (cmbgroup.SelectedValue != null)
id = int.Parse(cmbgroup.SelectedValue.ToString());
else id = 0;

if (newmode)
{

int result = clsbll.adduser(txtusername.Text.ToLower().Trim(), chkadmin.Checked,
id, txtpass1.Text.ToLower().Trim(), chkactive.Checked
, txtfname.Text.ToLower().Trim(), txtlname.Text.ToLower().Trim()
, txtfax.Text.ToLower().Trim(), txtemail.Text.ToLower().Trim(), usersdata);
if(result ==0)
MessageBox.Show("اطلاعات کاربر جدید ثبت گردید");
else if (result == -1)
{
MessageBox.Show("اطلاعات کاربر تکراری می باشد");
datanav1.addoreditmode();
return;

}
else MessageBox.Show("خطا در ثبت اطلاعات" + clsmain.except.ToString());

}
}


آیا روش من صحیح می باشد از SP هم استفاده نمودم باز هم همین مشکل و جود داشت یا در استفاده از INDENTITY این مشکل وجود دارد حتی با استفاده از TRANSACTION ?????

gwbasic
سه شنبه 15 فروردین 1391, 10:16 صبح
وقتی فیلدی را از نوع Identity تعریف می کنید مکانیزم مقدار دهی توسط خود Database انجام می شود و ربطی به EF ندارد. دقت کنید که مقدار جاری id در DB جای دیگری ذخیره می شود به همین دلیل است که این مشکل برای شما بوجود می آید.
فرضا شما رکوردی را درج کرده اید که Id آن 18 می باشد سپس آنرا حذف می کنید توقع دارید که هنگام درج رکورد دیگر این مقدار یعنی 18 به ID آن اختصاص داده شود که نمی شود (البته دلیل منطقی هم وجود دارد)
برای تغییر مقدار جاری Id می تونید از اسکریپ زیر استفاده کنید

DBCC CHECKIDENT ("MYTable",reseed,17)

amir3321
سه شنبه 15 فروردین 1391, 13:04 عصر
با سلام خدمت استاد gwbasic عزیز
با تشکر از راهنمایی ارزشمند شما در حال کار روی یک پروژه متوسط می باشم یک امتحان نمودم ، بین همین تابع بالا که از transaction scop در ef استفاده کردم با یک sp که آن را تبدیل به یک تابع نمودم و امتحان نمودم سرعت اجرا بوسیله sp ی که تابع شده چشمگیر بود ایا مشکل در نوع تابع نویسی من در transaction scop بوده است یا عملا ef از sp نوشته شده در دیتابیس کندتر عمل میکند .

یک مورد دیگر که مشکل داشتم مثلا من یک sp در دیتابیس می نویسم مانند همین تابع بالا که نیاز دارم در آن همزمان در دو جدول ثبت نمایم پس لزوما پارامتر های ورودی من بیشتر از فیلدهای جدول اصلی می باشد که من می خواهم این sp رو به insert ان map کنم یعنی در این صورت من فقط بصورت یک تابع می تونم از این sp در ef استفاده کنم ایا این درست است .

amir3321
چهارشنبه 16 فروردین 1391, 09:37 صبح
استاد منتظریم