Reputation: 740
I have an entity of a physical file location:
public class MyFile
{
public MyFile() { }
public int FileID { get; set; }
public string URI { get; set; }
DisposeFile()
{
//Remove physicall file here...
}
}
I want the DisposeFile()
method to be called when I remove MyFile
entity from the database:
DbContext.MyFile.Remove(someMyFileEntity);
DbContext.SaveChanges(); // Call DisposeFile()
Is there a simple way to do so? Or should I dispose this physical file in other way?
Upvotes: 0
Views: 825
Reputation: 3154
You can easily achieve what you are looking for by overriding the SaveChanges
method of your DbContext
class:
public override int SaveChanges()
{
var deletedMyFileEntityList = ChangeTracker.Entries()
.Where(f => f.Entity is MyFile && f.State == EntityState.Deleted);
foreach (var entity in deletedMyFileEntityList)
{
try {
entity.DisposeFile();
}
catch (Exception ex)
{
// Here you can decide what to do if the DisposeFile method fails
}
}
return base.SaveChanges();
}
Upvotes: 0
Reputation: 1349
It can also be done by overriding the savechanges method in EF.
var db = new RBSYNERGYEntities();
tblProductMaster master = db.tblProductMasters.FirstOrDefault();
db.tblProductMasters.Remove(master);
db.SaveChanges();
and in model.Context.cs
public partial class RBSYNERGYEntities : DbContext
{
//Other is ommited
public override int SaveChanges()
{
var changedEntities = ChangeTracker.Entries();
foreach (var changedEntity in changedEntities)
{
if (changedEntity.State == System.Data.Entity.EntityState.Deleted)
{
tblProductMaster info = changedEntity.Entity as tblProductMaster;
if (info != null)
{
//Do your work here
int a = 0;
}
}
}
return base.SaveChanges();
}
}
Upvotes: 0
Reputation: 3750
I agree with @ChrisBint that this kind of operations should be placed into a service, but you can take a look a this project.
Taken from their page:
EFHooks is a framework to assist in hooking into the Entity Framework Code First before and after insert, update and delete actions are performed on the database.
EFHooks is designed to lend itself to code that is easy to unit test with the least amount of mocking possible and without cluttering up your DbContext class with hooking code. It also is designed to play well with IoC containers.
Getting Started:
Define a hook to fire before an action by deriving from one of the strongly typed hook classes: PreInsertHook<TEntity>
, PreUpdateHook<TEntity>
or PreDeleteHook<TEntity>
and override the Hook method. (There are also Post-Action hooks)
The example below will automatically set the CreatedAt property to DateTime.Now
public class TimestampPreInsertHook : PreInsertHook<ITimeStamped>
{
public override void Hook(ITimeStamped entity, HookEntityMetadata metadata)
{
entity.CreatedAt = DateTime.Now;
}
}
Then derive your DbContext
from the EFHooks.HookedDbContext
and register the hooks.
public class AppContext : HookedDbContext
{
public AppContext() : base()
{
this.RegisterHook(new TimestampPreInsertHook());
}
public DbSet<User> Users { get; set; }
public DbSet<Post> Posts { get; set; }
}
New up the AppContext
and your hooks are in place and will fire when you call SaveChanges();
Upvotes: 0
Reputation: 12904
Ideally, this kind of method would go into a 'Service', which you would then call a method on this service to do both delete from the context, and deleting the physical file.
Upvotes: 2