@ -8,7 +8,7 @@ ABP defines some filters out of the box.
### ISoftDelete
Used to mark an entity as deleted instead of actually deleting it. Implement the `ISoftDelete` interface to make your entity "soft delete".
Used to mark an [entity](Entities.md) as deleted instead of actually deleting it. Implement the `ISoftDelete` interface to make your entity "soft delete".
> Carefully change defaults for global filters, especially if you are using a pre-built module which might be developed assuming the soft delete filter is turned on by default. But you can do it for your own defined filters safely.
> Carefully change defaults for global filters, especially if you are using a pre-built module which might be developed assuming the soft delete filter is turned on by default. But you can do it for your own defined filters safely.
## Defining Custom Filters
Defining and implementing a new filter highly depends on the database provider. ABP implements all pre-defined filters for all database providers.
When you need it, start by defining an interface (like `ISoftDelete` and `IMultiTenant`) for your filter and implement it for your entities.
Example:
````csharp
public interface IIsActive
{
bool IsActive { get; }
}
````
Such an `IIsActive` interface can be used to filter active/passive data and can be easily implemented by any [entity](Entities.md):
````csharp
public class Book : AggregateRoot<Guid>, IIsActive
{
public string Name { get; set; }
public bool IsActive { get; set; } //Defined by IIsActive
}
````
### EntityFramework Core
ABP uses [EF Core's Global Query Filters](https://docs.microsoft.com/en-us/ef/core/querying/filters) system for the [EF Core Integration](Entity-Framework-Core.md). So, it is well integrated to EF Core and works as expected even if you directly work with `DbContext`.
Best way to implement a custom filter is to override `CreateFilterExpression` method for your `DbContext`. Example:
var expression = base.CreateFilterExpression<TEntity>();
if (typeof(IIsActive).IsAssignableFrom(typeof(TEntity)))
{
Expression<Func<TEntity,bool>> isActiveFilter =
e => !IsActiveFilterEnabled || EF.Property<bool>(e, "IsActive");
expression = expression == null
? isActiveFilter
: CombineExpressions(expression, isActiveFilter);
}
return expression;
}
````
* Added a `IsActiveFilterEnabled` property to check if `IIsActive` is enabled or not. It internally uses the `IDataFilter` service introduced before.
* Overrided the `CreateFilterExpression` method, checked if given entity implements the `IIsActive` interface and combines the expressions if necessary.
### MongoDB
ABP implements data filters directly in the [repository](Repositories.md) level for the [MongoDB Integration](MongoDB.md). So, it works only if you use the repositories properly. Otherwise, you should manually filter the data.
Currently, the best way to implement a data filter for the MongoDB integration is to override the `AddGlobalFilters` in the repository derived from the `MongoDbRepository` class. Example:
````csharp
public class BookRepository : MongoDbRepository<BookStoreMongoDbContext,Book,Guid>
This example implements it only for the `Book` entity. If you want to implement for all entities (those implement the `IIsActive` interface), create your own custom MongoDB repository base class and override the `AddGlobalFilters` as shown below:
````csharp
public abstract class MyMongoRepository<TMongoDbContext,TEntity,TKey> : MongoDbRepository<TMongoDbContext,TEntity,TKey>
> See "Set Default Repository Classes" section of the [MongoDb Integration document](MongoDB.md) to learn how to replace default repository base with your custom class.