ArchivableRepository

Feb 22, 2012 at 4:49 PM

Hi,

I'm using EntityFramework.Patterns in my application and I need to implement soft deletion.  Is it possible to implement it using ArchivableRepository ?

If yes can you describe how ?

Do you have any documentation for ArchivableRepository?

 

Thanks mrio

Coordinator
Feb 23, 2012 at 10:12 PM

Hi Mrio,

yes it's very easy to implement soft deletion with EntityFramework.Patterns.

Your entities must implement the IArchivable interface and then you should use the ArchivableRepository.

Note that if your using EF code first, instead of implementing the IArchivable interface you can decorate your entities with the ArchivableAttribute like this :

    [Archivable]
    public class WorkBench
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

And the post compilation task will implement the IArchivable interface automatically for you.

Once IArchivable interface is implemented, wrap your Repository around an ArchivableRepository like that :

            using (EfContext ctx = new EfContext())
            {
                DbContextAdapter adpt = new DbContextAdapter(ctx);
                IRepository<WorkBench> repo =
                    new ArchivableRepository<WorkBench>(
                        new Repository<WorkBench>(adpt)
                        );

                IEnumerable<WorkBench> a = repo.GetAll(); 
               repo.Delete(a.First());
}

The delete method will not really delete the row in your db, but instead will set the properties Deleted and DeletedBy (IArchivable interface).

Subsequent queries will not return elements whose Deleted property is not null.

Regarding the documentation, I'll try to add a section on this subject.

I hope this answer will help you to achieve your goal.

Feb 24, 2012 at 8:55 AM
Edited Feb 24, 2012 at 10:32 AM

Than you a lot, it really helped me.

I have one more question.

Is it possible to call custom select statement using linq through ArchivableRepository ?

I'm working on tables with big amount of data and sometimes I need to count row. The only way I know (using ArchivableRepository)  is to call Find(....) method and then count objects in IEnumerable<T> but this approach  require to load all data to memory and I can't afford for this.

 I mean sth like that : (this is not correct because deleted rows will be also included)

repo = new ArchivableRepository<T>(....);
var result = from u in repo.AsQueryable()
select u;

 

Thank you for your time.

 

 

 

Coordinator
Feb 24, 2012 at 9:47 PM
Edited Feb 26, 2012 at 3:41 PM

mrio,

If you want to count rows directly on your db server and not in memory you should use something like this :

repo.AsQueryable().Count()

Unfortunately archived rows are not filtered out when using AsQueryable; this will be fix in the future version.

A workaround is to manually filter those elements :

repo.AsQueryable().Count(wb => wb.Deleted == null)

The resulting SQL will look like this :

SELECT 
[GroupBy1].[A1] AS [C1]
FROM ( SELECT 
	COUNT(1) AS [A1]
	FROM [dbo].[WorkBenches] AS [Extent1]
	WHERE [Extent1].[Deleted] IS NULL
)  AS [GroupBy1]

Is this acceptable?

Feb 26, 2012 at 2:07 PM

Thanks you Fab_Michellonet. Yes it is acceptable. I known about it but I thought that there is another way.

In my code I override the method AsQueryable() to base.AsQueryable().where(....)

 

Thank you for your help