wk4questions
wk4questions

Reputation: 135

Generic Delete in Entity Framework

I have a generic delete method DoDelete<MyTable>(int batchSize, MyDatabaseContext)

This methods builds up ids (List<int> deleteId) upto the batchsize count and then I like to call

BulkDelete<T>(MyDatabaseContext, t => deleteId.Contains(t.RecordId)) 

However this approach does not work because its unaware that <t> has property RecordId (even though it will always be RecordId property).

I have also tried:

int rows = BulkDelete<T>(MyDatabaseContext, "RecordId in (100001,100002)");

This is actual method that does the delete, I have also an overload that accepts string predicate.

public int BulkDelete<T>(MyDatabaseContext context, Expression<Func<T,   bool>> predicate)
where T : class
{
    int rows = context.Set<T>().Where(predicate).Delete();

    return rows;
}

Upvotes: 0

Views: 2891

Answers (2)

Rhumborl
Rhumborl

Reputation: 16609

As @mason says, you can create an interface with a RecordId property that all your entities implement, then your generic t=>deleteId.Contains(t.RecordId) will compile:

// The interface
public interface IRecordIdEntity
{
    int RecordId {get;set;}
}

// Sample Class
public class Person : IRecordIdEntity
{
   // implement the interface
   public int RecordId {get;set;} 
}

// Generic BulkDelete for IRecordIdEntitys
public int BulkDelete<T>(MyDatabaseContext context, Expression<Func<T, bool>> predicate)
    where T : IRecordIdEntity
{
    int rows = context.Set<T>().Where(predicate).Delete();

    return rows;
}

// Sample call
BulkDelete<Person>(MyDatabaseContext, person=> deleteId.Contains(person.RecordId)) 

Now that BulkDelete() is restricted to working on types implementing IRecordIdEntity the predicate is always valid.

Upvotes: 5

Szer
Szer

Reputation: 3476

First of all you should use interface to work with:

public interface IEntity
{
    long RecordId { get; set; }
}

Then you should do so that every other Entity object (table) implement that interface:

//Example
public class Book : IEntity
{
    public long RecordId { get; set; }
    public string Name { get; set; }
    public string Author{ get; set; }
}

After that you could easily add constraint to your method:

    public int BulkDelete<T>(MyDatabaseContext context, Expression<Func<T, bool>> predicate)
        where T : class, IEntity
    {
        int rows = context.Set<T>()
            .Where(predicate).Delete();

        return rows;
    }

And after that this call will be good to go because t is IEntity:

BulkDelete<T>(MyDatabaseContext, t=>deleteId.Contains(t.RecordId)) 

Upvotes: 1

Related Questions