View Full Version : Update یک جدول و ثبت تاریخ Update در جدولی دیگر
fardin_esmi
جمعه 16 مهر 1395, 23:29 عصر
با سلام و وقت بخیر
من دو جدول دارم که با هم رابطه one- to - many دارند . می خوام وقتی مقادیر جدول اول توسط کاربر ویرایش شد ، تاریخ ویرایش در یک جدول دیگر ثبت شود. با استفاده از EF Code First .
کلاس هایی که دارم به این صورت هست:
public class GroupAndChannel
{
//از اینجا
public GroupAndChannel()
{
GacId = Guid.NewGuid();
}
[Key]
public Guid GacId { get; set; }
//تا اینجا برای ایجاد آی دی
//این آی دی مربوط به جدول سوم هست که در سوال من مهم نیست
[ForeignKey("ApplicationUser")]
public string UserId { get; set; }
public virtual ApplicationUser ApplicationUser { get; set; }
// ایجاد رابطه یک به چند با جدول اول
public virtual ICollection<RegisterModified> RegisterModifieds { get; set; }
public string UserEmail { get; set; }
public string JoinLink { get; set; }
public int Members { get; set; }
و کلاس دیگه هم به صورت زیر :
public class RegisterModified
{
//از اینجا
public RegisterModified()
{
RegisterModifiedId = Guid.NewGuid();
}
[Key]
public Guid RegisterModifiedId { get; set; }
//تا اینجا برای ایجاد آی دی
//آی دی جدول دوم
public Guid GacId { get; set; }
[ForeignKey("GacId")]
public virtual GroupAndChannel GrupAndChannels { get; set; }
// پراپرتی تاریخ برای ثبت تاریخ ویرایش جدول دوم
public DateTime ModifyDate { get; set; }
}
در Action Result Edit چه کار کنم؟
راه حل یا مقاله یا مثالی که روش رو نشون بده هم خوبه.
با روش زیر من نتونستم این کار رو انجام بدم :
ساخت یک ویو مدل از هردو کلاس ، ارسال به Edit View ، و در متد Post اکشن Edit به این صورت نوشتم :
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(EditDataViewModel model)
{
if (ModelState.IsValid)
{
GroupAndChannel groupAndChannel = new GroupAndChannel();
groupAndChannel.UserEmail = Session["Email"].ToString();
groupAndChannel.UserId = Session["UserId"].ToString();
groupAndChannel.JoinLink = model.JoinLink;
groupAndChannel.Members = model.Members;
groupAndChannel.GacId = model.GacId;
var rm = new RegisterModified
{
GacId = model.GacId,
ModifyDate = DateTime.Now
};
db.Entry(groupAndChannel).State = EntityState.Modified;
// از خط زیر ایراد میگیره
db.RegisterModifieds.Add(rm);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(model);
اینم عکس خطایی که میگیره:
142925
پیشاپیش از راهنمایی شما متشکرم.
ali_md110
شنبه 17 مهر 1395, 00:11 صبح
شما دارید یک رکورد جدید درج Addمیکنید بجاش بایدAttach کنید
و چون رابطه یک به چند دارید ممکنه GacId درون جدول Register چند تا موجود باشه
ابتدا با متد find درون یک حلقه بر روی لیست db.RegisterModifieds که دارید جستجو بزنید
بعد دستور Attach
رو روی dbset اجرا کنید
هم میتونید از عبارات لامبدا استفاده کنید و هم حلقه
fardin_esmi
شنبه 17 مهر 1395, 08:38 صبح
ممنون به خاطر جوابتون.
من آی دی رو در اینجا برای rm مشخص کردم :
var rm = new RegisterModified
{
GacId = model.GacId,
ModifyDate = DateTime.Now
};
ولی با Attach هم که به صورت زیر نوشتم همون خطا رو میده .
db.RegisterModifieds.Attach(rm);
نکته دیگه اینکه من توی جدول RegisterModifieds اصلا رکوردی ندارم که بخوام جستجو کنم . اولین رکورد رو میخوام ثبت کنم.
این قسمت رو متوجه نشدم :
ابتدا با متد find درون یک حلقه بر روی لیست db.RegisterModifieds که دارید جستجو بزنید
بعد دستور Attach
رو روی dbset اجرا کنید
میشه لطفا تکه کد رو قرار بدید؟
ممنون
ali_md110
شنبه 17 مهر 1395, 14:18 عصر
بله حق با شماست من سوال شما رو خوب متوجه نشدم کمی خوابالود بودم فکر کردم میخاید در جدول دوم ویرایش انجام بدید
همون متد Add صحیح هست
این یک خطای null reference هست یعنی یک شی وهله سازی نشده
به نظر من شی db شما که همون DataContext شما هست وهله سازی نشده
یک بار دیگه قبل از متد Add وهله سازی کنید
var db= new اسم کانتکست
fardin_esmi
یک شنبه 18 مهر 1395, 10:50 صبح
این که db وهله سازی نشده نمی تونه درست باشه چون db در سطح کلاس یک بار تعریف و قبل از اکشن Edit و هم داخل آن چند بار استفاده شده است.
به هرحال پیشنهاد شما رو امتحان کردم که همون خطا رو داد.
hp1361
یک شنبه 18 مهر 1395, 11:43 صبح
با سلام و وقت بخیر
من دو جدول دارم که با هم رابطه one- to - many دارند . می خوام وقتی مقادیر جدول اول توسط کاربر ویرایش شد ، تاریخ ویرایش در یک جدول دیگر ثبت شود. با استفاده از EF Code First .
کلاس هایی که دارم به این صورت هست:
public class GroupAndChannel
{
//از اینجا
public GroupAndChannel()
{
GacId = Guid.NewGuid();
}
[Key]
public Guid GacId { get; set; }
//تا اینجا برای ایجاد آی دی
//این آی دی مربوط به جدول سوم هست که در سوال من مهم نیست
[ForeignKey("ApplicationUser")]
public string UserId { get; set; }
public virtual ApplicationUser ApplicationUser { get; set; }
// ایجاد رابطه یک به چند با جدول اول
public virtual ICollection<RegisterModified> RegisterModifieds { get; set; }
public string UserEmail { get; set; }
public string JoinLink { get; set; }
public int Members { get; set; }
و کلاس دیگه هم به صورت زیر :
public class RegisterModified
{
//از اینجا
public RegisterModified()
{
RegisterModifiedId = Guid.NewGuid();
}
[Key]
public Guid RegisterModifiedId { get; set; }
//تا اینجا برای ایجاد آی دی
//آی دی جدول دوم
public Guid GacId { get; set; }
[ForeignKey("GacId")]
public virtual GroupAndChannel GrupAndChannels { get; set; }
// پراپرتی تاریخ برای ثبت تاریخ ویرایش جدول دوم
public DateTime ModifyDate { get; set; }
}
در Action Result Edit چه کار کنم؟
راه حل یا مقاله یا مثالی که روش رو نشون بده هم خوبه.
با روش زیر من نتونستم این کار رو انجام بدم :
ساخت یک ویو مدل از هردو کلاس و ارسال به Edit View و در مثد Post از اکشن Edit به این صورت نوشتم :
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(EditDataViewModel model)
{
if (ModelState.IsValid)
{
GroupAndChannel groupAndChannel = new GroupAndChannel();
groupAndChannel.UserEmail = Session["Email"].ToString();
groupAndChannel.UserId = Session["UserId"].ToString();
groupAndChannel.JoinLink = model.JoinLink;
groupAndChannel.Members = model.Members;
groupAndChannel.GacId = model.GacId;
var rm = new RegisterModified
{
GacId = model.GacId,
ModifyDate = DateTime.Now
};
db.Entry(groupAndChannel).State = EntityState.Modified;
// از خط زیر ایراد میگیره
db.RegisterModifieds.Add(rm);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(model);
اینم عکس خطایی که میگیره:
142925
پیشاپیش از راهنمایی شما متشکرم.
سلام
با فرض اینکه مقدار model.GacId درون دیتابیس وجود داره، به این صورت ذخیره کنید:
if (ModelState.IsValid)
{
var rm = new RegisterModified
{
ModifyDate = DateTime.Now
};
GroupAndChannel groupAndChannel = new GroupAndChannel();
groupAndChannel.UserEmail = Session["Email"].ToString();
groupAndChannel.UserId = Session["UserId"].ToString();
groupAndChannel.JoinLink = model.JoinLink;
groupAndChannel.Members = model.Members;
groupAndChannel.GacId = model.GacId;
db.Entry(groupAndChannel).State = EntityState.Modified;
groupAndChannel.RegisterModifieds.add(rm);
db.SaveChanges();
return RedirectToAction("Index");
}
fardin_esmi
دوشنبه 19 مهر 1395, 09:40 صبح
با فرض اینکه مقدار model.GacId درون دیتابیس وجود داره، به این صورت ذخیره کنید:
منظورتون اینه که GacId رو جداگانه به جدول اضافه کنم؟
با برداشتن GacId از rm خطای قبلی رو میده ضمن اینکه GacId به صورت زیر میشه.
{00000000-0000-0000-0000-000000000000}
ما برای اینکه بدونیم کدوم رکورد از جدول GroupsAndChannels تغییر کرده باید GacId از این جدول رو در جدول RegisterModifieds ذخیره کنیم . برای همین من یه آی دی با همین اسم توی جدول دوم (جدا از آی دی خود جدول )هم در نظر گرفتم . به کدهای کلاس RegisterModified توجه کنید.
شاید ارتباط این جدول یک به چند نیست ؟ شاید مشکل از اینجا باشه . نظری دارید؟
-هر رکورد از جدول شماره یک می تواند جند تغییر در جدول 2 داشته باشد
-هر تغییر مربوط به یک رکورد است
ضمنا من از این دوروش هم استفاده کردم:
public void InsertTo(Guid gi)
{
string conn = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
SqlConnection con = new SqlConnection(conn);
string query = "Insert into RegisterModifieds(GacId,ModifyDate)Values(" + gi + "," + DateTime.Now + ")";
con.Open();
SqlCommand cmd = new SqlCommand(query, con);
cmd.ExecuteNonQuery();
} con.Close();
و این روش :
public void InsertTo(Guid gi)
{
db.Database.ExecuteSqlCommand("Insert Into RegisterModifieds( GacId,ModifyDate)Values(" + gi + "','" + DateTime.Now + "')'");
db.RegisterModifieds.Add(reg);
db.SaveChanges();
}
ولی خطاهاش یادم نیست چی بود . اگه لازمه دوباره بذارم؟
ممنون از وقتی که میذارید.
ali_md110
دوشنبه 19 مهر 1395, 12:23 عصر
وقتی رابطه یک به چند داریم برای درج یا ویرایش همزمان دو جدول میتونیم به روش دوستوم HP-1361 گفتند انجام بدیم
اول اینکه یک لیست از نوع جدول فرزند در کلاس پدر داریم بدین صورت
// ایجاد رابطه یک به چند با جدول اولpublic virtual ICollection<RegisterModified> RegisterModifieds { get; set; }
براب درج رکورد جدبد در جدول پدر ابتدا یک شی از نوع پدر میسازیم
var model= new GroupAndChannel();
برای ویرایش اگر شی پدر موجود بود
که در اینجا همون EditDataViewModel model ورودی شماست
حالا وقتی رکورد با دیتای جدول پدر درونش ریخیتم یا ویرایش کردیم
میتونبم با وهله سازی یک لیست و انتصاب اون به لیست RegisterModifieds در جدول پدر رکوردها رو در جدول فرزند درج کنیم
model.RegisterModifieds.Add
new List<RegisterModified>
{
var rm = new RegisterModified {
ModifyDate = DateTime.Now
};
}
در ضمن کانکشن یا db شما در کجا وهله سازی میشه؟ اگر در همین اکشن Edit هست موردی ندارید ولی اگر در جای دیگه وهله سازی میکنید و در تمام اکشن های یک کنترولر استفاده می کنید روش خودتون رو اصلاح کینید و یک کانکگشن باز به ازای چند تراکنش در چند متد رو استفاده نکنید
property های شما بصورت Virtual هست پس سازنده کلاس رو هم حذف کنید دیگر نیازی نیست
و مقداری دهی فیلد GUID در زمان وهله سازی انجام بدبد
fardin_esmi
سه شنبه 25 آبان 1395, 13:13 عصر
من واقعا به خاطر وقتی که گذاشتید ازتون ممنونم .
با راهنمایی هایی که کردید تونستم مشکل رو به این صورت حل کنم :
var rm=db.RegisterModifieds.Add(new RegisterModified
{
GacId = groupAndChannel.GacId,
ModifyDate = DateTime.Now
});
db.Entry(groupAndChannel).State = EntityState.Modified;
groupAndChannel.RegisterModifieds.Add(rm);
db.SaveChanges();
ویرایش:
فک کنم دلیل این بود که من از کلاس RegisterModified فقط نمونه سازی می کردم و به دیتابیس اضافه نمی کردم به همین دلیل وقتی میخواستم اونو به groupAndChannel اضافه کنم خطای خالی بودن مقدار رو میداد.
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.