Reputation: 60674
I am quite sure I've seen the answer to this question somewhere, but as I couldn't find it with a couple of searches on SO or google, I ask it again anyway...
In Entity Framework, the only way to delete a data object seems to be
MyEntityModel ent = new MyEntityModel();
ent.DeleteObject(theObjectToDelete);
ent.SaveChanges();
However, this approach requires the object to be loaded to, in this case, the Controller first, just to delete it. Is there a way to delete a business object referencing only for instance its ID?
If there is a smarter way using Linq or Lambda expressions, that is fine too. The main objective, though, is to avoid loading data just to delete it.
Upvotes: 40
Views: 37371
Reputation: 904
It is worth knowing that the Entity Framework supports both to Linq to Entities and Entity SQL. If you find yourself wanting to do deletes or updates that could potentially affect many records you can use the equivalent of ExecuteNonQuery
.
In Entity SQL this might look like
Using db As New HelloEfEntities
Dim qStr = "Delete " & _
"FROM Employee"
db.ExecuteStoreCommand(qStr)
db.SaveChanges()
End Using
In this example, db
is my ObjectContext
. Also note that the ExecuteStoreCommand
function takes an optional array of parameters.
Upvotes: 19
Reputation: 3757
You can create an object with the same id and pass it through to the delete BUT its good for simple objects if you have complex relations you may need more than that
var user = new User { ID = 15 };
context.Entry(user).State = EntityState.Deleted;
context.SaveChanges();
Upvotes: 4
Reputation: 17272
With Entity Framework 5 there is Entity Framework Extended Library. Available on NuGet. Then you can write something like:
context.Users.Delete(u => u.Id == id);
It is also useful for bulk deletes.
Upvotes: 2
Reputation: 35135
var toDelete = new MyEntityModel{
GUID = guid,
//or ID = id, depending on the key
};
Db.MyEntityModels.Attach(toDelete);
Db.MyEntityModels.DeleteObject(toDelete);
Db.SaveChanges();
In case your key contains multiple columns, you need to provide all values (e.g. GUID, columnX, columnY etc).
Have also a look here for a generic function if you feel for something fancy.
Upvotes: 3
Reputation: 4739
There's a way to spoof load an entity by re-calculating it's EntityKey. It looks like a bit of a hack, but might be the only way to do this in EF.
Blog article on Deleting without Fetching
Upvotes: 4
Reputation: 126587
Apologies in advance, but I have to question your goal.
If you delete an object without ever reading it, then you can't know if another user has changed the object in between the time you confirmed that you wanted to delete the object and the actual delete. In "plain old SQL", this would be like doing:
DELETE FROM FOO
WHERE ID = 1234
Of course, most people don't actually do this. Instead, they do something like:
DELETE FROM FOO
WHERE ID = 1234
AND NAME = ?ExpectedName AND...
The point is that the delete should fail (do nothing) if another user has changed the record in the interim.
With this, better statement of the problem, there are two possible solutions when using the Entity Framework.
In your Delete method, the existing instance, compare the expected values of the properties, and delete if they are the same. In this case, the Entity Framework will take care of writing a DELETE statement which includes the property values.
Write a stored procedure which accepts both the IDE and the other property values, and execute that.
Upvotes: 4
Reputation: 60674
I found this post, which states that there really is no better way to delete records. The explanation given was that all the foreign keys, relations etc that are unique for this record are also deleted, and so EF needs to have the correct information about the record. I am puzzled by why this couldn't be achieved without loading data back and forth, but as it's not going to happen very often I have decided (for now) that I won't bother.
If you do have a solution to this problem, feel free to let me know =)
Upvotes: 8