J'ai une table SQL Server dans Entity Framework nommée employ
avec une seule colonne de clé nommée ID
.
Comment supprimer un seul enregistrement de la table à l'aide d'Entity Framework?
J'ai une table SQL Server dans Entity Framework nommée employ
avec une seule colonne de clé nommée ID
.
Comment supprimer un seul enregistrement de la table à l'aide d'Entity Framework?
Réponses:
Il n'est pas nécessaire d'interroger d'abord l'objet, vous pouvez le joindre au contexte par son identifiant. Comme ça:
var employer = new Employ { Id = 1 };
ctx.Employ.Attach(employer);
ctx.Employ.Remove(employer);
ctx.SaveChanges();
Vous pouvez également définir l'état de l'entrée jointe sur supprimé:
var employer = new Employ { Id = 1 };
ctx.Entry(employer).State = EntityState.Deleted;
ctx.SaveChanges();
ctx.Entry(employer).State = EntityState.Deleted
Vous pouvez utiliser SingleOrDefault
pour obtenir un seul objet correspondant à vos critères, puis le transmettre à la Remove
méthode de votre table EF.
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
est dangereux. Soit vous savez qu'il n'y en a qu'un (alors utilisez SingleOrDefault
), soit il y en a plus d'un, et cela devrait être fait en boucle.
Employer employer = context.Employers.First(x => x.EmployerId == 1);
context.Customers.DeleteObject(employer);
context.SaveChanges();
First
est dangereux. Soit vous savez qu'il n'y en a qu'un (alors utilisez Single
), soit il y en a plus d'un, et cela devrait être fait en boucle.
J'utilise le framework d'entité avec LINQ. Le code suivant m'a été utile;
1- Pour plusieurs enregistrements
using (var dbContext = new Chat_ServerEntities())
{
var allRec= dbContext.myEntities;
dbContext.myEntities.RemoveRange(allRec);
dbContext.SaveChanges();
}
2- Pour un enregistrement unique
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
place de FirstOrDefault
?
Approche plus générique
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);
}
Avec Entity Framework 6, vous pouvez utiliser Remove
. C'est aussi une bonne tactique à utiliser using
pour être sûr que votre connexion est fermée.
using (var context = new EmployDbContext())
{
Employ emp = context.Employ.Where(x => x.Id == id).Single<Employ>();
context.Employ.Remove(emp);
context.SaveChanges();
}
Je voulais juste contribuer aux trois méthodes avec lesquelles j'ai rebondi.
Méthode 1:
var record = ctx.Records.FirstOrDefault();
ctx.Records.Remove(record);
ctx.SaveChanges();
Méthode 2:
var record = ctx.Records.FirstOfDefault();
ctx.Entry(record).State = EntityState.Deleted;
ctx.SaveChanges();
ctx.Entry(record).State = EntityState.Detached;
L'une des raisons pour lesquelles je préfère utiliser la méthode 2 est que dans le cas de la définition de EF ou EFCore QueryTrackingBehavior.NoTracking
, il est plus sûr de le faire.
Ensuite, il y a la méthode 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;
Cela utilise une approche de suppression logicielle en définissant la DeletedOn
propriété de l'enregistrement et en étant toujours en mesure de conserver l'enregistrement pour une utilisation future, quelle qu'elle soit. Fondamentalement, le mettre dans la corbeille .
En outre, en ce qui concerne la méthode 3 , au lieu de définir l'enregistrement entier à modifier:
entry.State = EntityState.Modified;
Vous devez également simplement définir uniquement la colonne DeletedOn
telle que modifiée:
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);
}
}
Que pensez-vous de cela, simple ou non, vous pouvez également essayer ceci:
var productrow = cnn.Product.Find(id);
cnn.Product.Remove(productrow);
cnn.SaveChanges();
Utiliser EntityFramework.Plus pourrait être une option:
dbContext.Employ.Where(e => e.Id == 1).Delete();
Plus d'exemples sont disponibles ici
tu peux le faire comme ça
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");
}
}
modèle
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; }
}
vue d'où tu l'appelleras
<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>
j'espère que ce sera facile à comprendre
Vous pouvez faire quelque chose comme ça dans votre événement click ou celldoubleclick de votre grille (si vous en avez utilisé un)
if(dgEmp.CurrentRow.Index != -1)
{
employ.Id = (Int32)dgEmp.CurrentRow.Cells["Id"].Value;
//Some other stuff here
}
Ensuite, faites quelque chose comme ceci dans votre bouton Supprimer:
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
}
Vous pouvez également utiliser une requête LINQ au lieu d'utiliser la requête LINQ To Entities:
var query = (from emp in db.Employee
where emp.Id == employ.Id
select emp).Single();
employ.Id est utilisé comme paramètre de filtrage qui a déjà été transmis à partir de l'événement CellDoubleClick de votre DataGridView.
Voici un moyen sûr:
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...
}
}
Ici, vous pouvez empiler toutes les modifications souhaitées, vous pouvez donc effectuer une série de suppressions avant les modifications et les validations, de sorte qu'elles ne seront appliquées que si elles réussissent toutes.