ورود

View Full Version : سوال: جلوگیری از ورود داده تکراری هنگام ویرایش



jafarpalideh
یک شنبه 15 اردیبهشت 1398, 10:12 صبح
سلام دوستان.
بهترین روش واسه اینکه موقع ویرایش چک کنیم که داده ی ویرایش شده تکراری نباشه چیه ؟
البته با Entity Framework
موقع ثبت راحت میشه چک کرد . موقع ویرایش چطور ؟
من تو جدولم 4 تا فیلد دارم آی دی(کلید اصلی) - کد - نام - نام خانوادگی اینجوری پر شده :

کد---------------------نام -----------------------نام خانوادگی

1----------------------علی ----------------------عالی


2--------------------حسن ---------------------صالحی


دو حالت داره:

اول:
کاربر کد رو ویرایش نمیکنه و فقط نام یا نام خانوادگی رو ویرایش میکنه
(اینجا رو چه کنم ؟)
دوم:
کاربر در رکورد دوم کد رو هم ویرایش میکنه و به جای 2 مینویسه 1
(اینجا رو چه کنم ؟)
این اکشن Create من هست و مشکل ندارم موقع ثبت باهاش



[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "PersonId,PersonCode,PersonName,PersonFamily")] People people)
{
if (ModelState.IsValid)
{
if (!db.People.Any(c=>c.PersonCode==people.PersonCode.Trim().ToLower()))
{
db.People.Add(people);
db.SaveChanges();
return RedirectToAction("Index");
}
else
{
ModelState.AddModelError("PersonCode", "کد وارد شده تکراری می باشد");
}

}


return View(people);
}


ولی اینجا تو ادیت چه کدی باس بنویسم واسه چک کردن ؟



[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "PersonId,PersonCode,PersonName,PersonFamily")] People people)
{
if (ModelState.IsValid)
{
db.Entry(people).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(people);
}

jafarpalideh
سه شنبه 17 اردیبهشت 1398, 13:47 عصر
دوستان راهکاری ندارن ؟

asiatec
سه شنبه 17 اردیبهشت 1398, 16:20 عصر
از db.addorupdate()

jafarpalideh
چهارشنبه 18 اردیبهشت 1398, 08:32 صبح
از db.addorupdate()

میشه یه توضیح بدید ؟

asiatec
چهارشنبه 18 اردیبهشت 1398, 11:14 صبح
به جای استفاده از

db.Entry(people).State = EntityState.Modified;
db.Add(people);



از

db.AddOrUpdate(people)

استفاده کنید

jafarpalideh
چهارشنبه 18 اردیبهشت 1398, 12:14 عصر
به جای استفاده از

db.Entry(people).State = EntityState.Modified;
db.Add(people);



از

db.AddOrUpdate(people)

استفاده کنید

راهکارش چیه واسه اینکه تشخیص بده یک رکورد نباس تکراری باشه یا اگه تکراری هست اعلام کنه ؟ من دقیق متوجه نمیشم

asiatec
چهارشنبه 18 اردیبهشت 1398, 13:15 عصر
اعلامی صورت نمیگیره اگر تکراری باشه اپدیت میشه نباشه رکورد جدید دخیره میشه

jafarpalideh
چهارشنبه 18 اردیبهشت 1398, 13:57 عصر
راه دیگه ای وجود نداره ؟
تویه ADO خیلی راحت بود . کد رو توی یه متغیر نگه میداشتم . موقع ویرایش میومدم و چک میکردم که آیا کد با اون متغیر یکی هست یا نه.
اگه مساوی بود که کوئری نمیزدم به دیتابیس. اما اگه فرق میکرد کوئری میزدم و چک میکردم که آیا وجود داره این کد و ارور رو نشون میدادم
این رو چطور میتونم پیاده سازی کنم ؟

ali_md110
چهارشنبه 18 اردیبهشت 1398, 18:45 عصر
سسیستم EF از Change Tracking یا سیستم ردیابی استفاده میکنه و تشخیص میده رکورد در چه وضعیتی قرار داره
آیا جدید هست یا قبلا بوده
شما کافیه یک جستجو بزنید بدینصورت



if (ModelState.IsValid) {
var first=db.people.FirstOrDefault(x=> x.PersonID==PersonId);
;
if(first!=null)
{
db.Entry(people).State = EntityState.Modified;
db.Attach(first);
db.SaveChanges();
return RedirectToAction("Index");

}
}
return View(people);

jafarpalideh
پنج شنبه 19 اردیبهشت 1398, 10:28 صبح
من اکشن رو به اینصورت تغییر دادم .



public ActionResult Edit([Bind(Include = "PersonId,PersonCode,PersonName,PersonFamily")] People people)
{
if (ModelState.IsValid)
{
var person = db.People.Find(people.PersonId);
if (person.PersonCode==people.PersonCode)
{
db.Entry(people).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
else
{
var personCode = db.People.SingleOrDefault(c => c.PersonCode == people.PersonCode);
if (personCode!=null)
{
ModelState.AddModelError("PersonCode", "کد وارد شده تکراری می باشد");
}
else
{
db.Entry(people).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
}
}
return View(people);
}


ولی موقع ویرایش ارور میده



System.InvalidOperationException: 'Attaching an entity of type 'DataLayer.People' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values.

jafarpalideh
پنج شنبه 19 اردیبهشت 1398, 12:50 عصر
این کد رو نوشتم و درست جواب میده .
به نظر شما بعدا دچار مشکل نمیشم با این کد ؟ یا اصلا کد ایرادی نداره ؟



public ActionResult Edit([Bind(Include = "PersonId,PersonCode,PersonName,PersonFamily")] People people)
{
if (ModelState.IsValid)
{
var person = db.People.Find(people.PersonId);
if (person.PersonCode==people.PersonCode)
{
if (person!=null)
{
db.Entry(person).State = EntityState.Detached;
}
db.Entry(people).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
else
{
var personCode = db.People.SingleOrDefault(c => c.PersonCode == people.PersonCode);
if (personCode!=null)
{
db.Entry(person).State = EntityState.Detached;
db.Entry(personCode).State = EntityState.Detached;
ModelState.AddModelError("PersonCode", "کد وارد شده تکراری می باشد");
}
else
{
db.Entry(person).State = EntityState.Detached;
db.Entry(people).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
}
}
return View(people);
}

ali_md110
پنج شنبه 19 اردیبهشت 1398, 16:20 عصر
کد قسمت else نیاز نیست فقط یک redirect کافیه
بدینصورت عمل کنید


if (ModelState.IsValid)
{
var person = db.People.Find(people.PersonId);
if (person != null)
{
if (person.PersonCode == people.PersonCode)
{
ModelState.AddModelError("PersonCode", "کد وارد شده تکراری می باشد");
}
else
{
// db.Entry(person).State = EntityState.Detached;
person.PersonId = people.PersonId;
person.PersonCode = people.PersonCode;
person.PersonName = people.PersonName;
person.PersonFamily = people.PersonFamily;
db.Attach(person);
db.Entry(person).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
}
}

return View(people);

میتونید از Automapper هم برای map شدن بهره ببرید

jafarpalideh
پنج شنبه 19 اردیبهشت 1398, 20:16 عصر
متاسفانه کدی که شما فرمودید جواب نمیده.
چون کاربر امکان داره کد پرسنلی رو تغییر نده و کد شما اجازه نمیده.مثلا کاربر میخواد نام رو عوض کنه ولی کد شما ارور میده چون میگه PersonCode تکراریه

ali_md110
جمعه 20 اردیبهشت 1398, 00:42 صبح
خب میتونید تمام فیلدها بجر PersonCode را به روزرسانی کنید



if (ModelState.IsValid)
{
var person = db.People.Find(people.PersonId);
var error = "";
if (person != null)
{
person.PersonId = people.PersonId;
person.PersonName = people.PersonName;
person.PersonFamily = people.PersonFamily;
if (person.PersonCode != people.PersonCode)
{
person.PersonCode = people.PersonCode;

}
else
{
// ModelState.AddModelError("PersonCode", "کد وارد شده تکراری می باشد");
error = "کد وارد شده تکراری می باشد";
}
db.Attach(person);
db.Entry(person).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
}

return View(people);