Ich habe eine SQL Server-Tabelle in Entity Framework employ
mit einer einzelnen Schlüsselspalte ID
.
Wie lösche ich einen einzelnen Datensatz mit Entity Framework aus der Tabelle?
Ich habe eine SQL Server-Tabelle in Entity Framework employ
mit einer einzelnen Schlüsselspalte ID
.
Wie lösche ich einen einzelnen Datensatz mit Entity Framework aus der Tabelle?
Antworten:
Es ist nicht erforderlich, das Objekt zuerst abzufragen. Sie können es anhand seiner ID an den Kontext anhängen. So was:
var employer = new Employ { Id = 1 };
ctx.Employ.Attach(employer);
ctx.Employ.Remove(employer);
ctx.SaveChanges();
Alternativ können Sie den Status des angehängten Eintrags auf gelöscht setzen:
var employer = new Employ { Id = 1 };
ctx.Entry(employer).State = EntityState.Deleted;
ctx.SaveChanges();
ctx.Entry(employer).State = EntityState.Deleted
Sie können SingleOrDefault
ein einzelnes Objekt verwenden, das Ihren Kriterien entspricht, und dieses dann an die Remove
Methode Ihrer EF-Tabelle übergeben.
var itemToRemove = Context.Employ.SingleOrDefault(x => x.id == 1); //returns a single item.
if (itemToRemove != null) {
Context.Employ.Remove(itemToRemove);
Context.SaveChanges();
}
var stud = (from s1 in entities.Students
where s1.ID== student.ID
select s1).SingleOrDefault();
//Delete it from memory
entities.DeleteObject(stud);
//Save to database
entities.SaveChanges();
FirstOrDefault
ist gefährlich. Entweder wissen Sie, dass es nur eine gibt (verwenden Sie also SingleOrDefault
), oder es gibt mehr als eine, und dies sollte in einer Schleife erfolgen.
Employer employer = context.Employers.First(x => x.EmployerId == 1);
context.Customers.DeleteObject(employer);
context.SaveChanges();
First
ist gefährlich. Entweder wissen Sie, dass es nur eine gibt (verwenden Sie also Single
), oder es gibt mehr als eine, und dies sollte in einer Schleife erfolgen.
Ich verwende das Entity Framework mit LINQ. Der folgende Code war hilfreich für mich;
1- Für mehrere Datensätze
using (var dbContext = new Chat_ServerEntities())
{
var allRec= dbContext.myEntities;
dbContext.myEntities.RemoveRange(allRec);
dbContext.SaveChanges();
}
2- Für einzelne Aufzeichnung
using (var dbContext = new Chat_ServerEntities())
{
var singleRec = dbContext.ChatUserConnections.FirstOrDefault( x => x.ID ==1);// object your want to delete
dbContext.ChatUserConnections.Remove(singleRec);
dbContext.SaveChanges();
}
SingleOrDefault
anstelle von verwenden FirstOrDefault
?
Allgemeiner Ansatz
public virtual void Delete<T>(int id) where T : BaseEntity, new()
{
T instance = Activator.CreateInstance<T>();
instance.Id = id;
if (dbContext.Entry<T>(entity).State == EntityState.Detached)
{
dbContext.Set<T>().Attach(entity);
}
dbContext.Set<T>().Remove(entity);
}
Mit Entity Framework 6 können Sie verwenden Remove
. Es ist auch eine gute Taktik, um using
sicherzustellen, dass Ihre Verbindung geschlossen ist.
using (var context = new EmployDbContext())
{
Employ emp = context.Employ.Where(x => x.Id == id).Single<Employ>();
context.Employ.Remove(emp);
context.SaveChanges();
}
Ich wollte nur die drei Methoden beisteuern, mit denen ich hin und her gesprungen bin.
Methode 1:
var record = ctx.Records.FirstOrDefault();
ctx.Records.Remove(record);
ctx.SaveChanges();
Methode 2:
var record = ctx.Records.FirstOfDefault();
ctx.Entry(record).State = EntityState.Deleted;
ctx.SaveChanges();
ctx.Entry(record).State = EntityState.Detached;
Einer der Gründe, warum ich mich für Methode 2 entscheide, ist QueryTrackingBehavior.NoTracking
, dass es sicherer ist, EF oder EFCore auf zu setzen.
Dann gibt es Methode 3:
var record = ctx.Records.FirstOrDefault();
var entry = ctx.Entry(record);
record.DeletedOn = DateTimeOffset.Now;
entry.State = EntityState.Modified;
ctx.SaveChanges();
entry.State = EntityState.Detached;
Dies verwendet einen Soft-Delete-Ansatz, indem die DeletedOn
Eigenschaft des Datensatzes festgelegt wird und der Datensatz dennoch für die zukünftige Verwendung aufbewahrt werden kann, was auch immer dies sein mag. Im Grunde genommen in den Papierkorb legen .
Auch in Bezug auf Methode 3 , anstatt den gesamten Datensatz so zu ändern, dass er geändert wird:
entry.State = EntityState.Modified;
Sie würden auch einfach nur die Spalte DeletedOn
als geändert festlegen :
entry.Property(x => x.DeletedOn).IsModified = true;
[HttpPost]
public JsonResult DeleteCotnact(int id)
{
using (MycasedbEntities dbde = new MycasedbEntities())
{
Contact rowcontact = (from c in dbde.Contact
where c.Id == id
select c).FirstOrDefault();
dbde.Contact.Remove(rowcontact);
dbde.SaveChanges();
return Json(id);
}
}
Was denkst du darüber, einfach oder nicht, du könntest es auch versuchen:
var productrow = cnn.Product.Find(id);
cnn.Product.Remove(productrow);
cnn.SaveChanges();
Die Verwendung von EntityFramework.Plus kann eine Option sein:
dbContext.Employ.Where(e => e.Id == 1).Delete();
Weitere Beispiele finden Sie hier
Du kannst es einfach so machen
public ActionResult Delete(int? id)
{
using (var db = new RegistrationEntities())
{
Models.RegisterTable Obj = new Models.RegisterTable();
Registration.DAL.RegisterDbTable personalDetail = db.RegisterDbTable.Find(id);
if (personalDetail == null)
{
return HttpNotFound();
}
else
{
Obj.UserID = personalDetail.UserID;
Obj.FirstName = personalDetail.FName;
Obj.LastName = personalDetail.LName;
Obj.City = personalDetail.City;
}
return View(Obj);
}
}
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int? id)
{
using (var db = new RegistrationEntities())
{
Registration.DAL.RegisterDbTable personalDetail = db.RegisterDbTable.Find(id);
db.RegisterDbTable.Remove(personalDetail);
db.SaveChanges();
return RedirectToAction("where u want it to redirect");
}
}
Modell-
public class RegisterTable
{
public int UserID
{ get; set; }
public string FirstName
{ get; set; }
public string LastName
{ get; set; }
public string Password
{ get; set; }
public string City
{ get; set; }
}
Ansicht, von der aus Sie es nennen werden
<table class="table">
<tr>
<th>
FirstName
</th>
<th>
LastName
</th>
<th>
City
</th>
<th></th>
</tr>
@foreach (var item in Model)
{
<tr>
<td> @item.FirstName </td>
<td> @item.LastName </td>
<td> @item.City</td>
<td>
<a href="@Url.Action("Edit", "Registeration", new { id = item.UserID })">Edit</a> |
<a href="@Url.Action("Details", "Registeration", new { id = item.UserID })">Details</a> |
<a href="@Url.Action("Delete", "Registeration", new { id = item.UserID })">Delete</a>
</td>
</tr>
}
</table>
Ich hoffe, das wird für dich leicht zu verstehen sein
Sie können so etwas in Ihrem Klick- oder Celldoubleclick-Ereignis Ihres Rasters tun (falls Sie eines verwendet haben).
if(dgEmp.CurrentRow.Index != -1)
{
employ.Id = (Int32)dgEmp.CurrentRow.Cells["Id"].Value;
//Some other stuff here
}
Dann machen Sie so etwas in Ihrer Löschtaste:
using(Context context = new Context())
{
var entry = context.Entry(employ);
if(entry.State == EntityState.Detached)
{
//Attached it since the record is already being tracked
context.Employee.Attach(employ);
}
//Use Remove method to remove it virtually from the memory
context.Employee.Remove(employ);
//Finally, execute SaveChanges method to finalized the delete command
//to the actual table
context.SaveChanges();
//Some stuff here
}
Alternativ können Sie eine LINQ-Abfrage anstelle der LINQ-Abfrage für Entitäten verwenden:
var query = (from emp in db.Employee
where emp.Id == employ.Id
select emp).Single();
Employ.Id wird als Filterparameter verwendet, der bereits vom CellDoubleClick-Ereignis Ihrer DataGridView übergeben wurde.
Hier ist ein sicherer Weg:
using (var transitron = ctx.Database.BeginTransaction())
{
try
{
var employer = new Employ { Id = 1 };
ctx.Entry(employer).State = EntityState.Deleted;
ctx.SaveChanges();
transitron.Commit();
}
catch (Exception ex)
{
transitron.Rollback();
//capture exception like: entity does not exist, Id property does not exist, etc...
}
}
Hier können Sie alle gewünschten Änderungen stapeln, sodass Sie vor SaveChanges und Commit eine Reihe von Löschvorgängen durchführen können, damit sie nur angewendet werden, wenn sie alle erfolgreich sind.