You should always strive to maintain the Domain-Driven Design (DDD) and Separation of Concerns by creating a custom repository in the .EntityFrameworkCore which you can then inject into the application or domain layers.
- Create a repository interface in .Core
- Create the repository implementation in .EntityFrameworkCore in Repositories
- Inherit from
EfCoreRepositoryBase
and your interface - Inject
IDbContextProvider
andIActiveTransactionProvider
into the constructor - Create private fields to reference the injected objects
- Inherit from
- Add the custom functions for your repository
- Use the custom repository in your domain service
Each step is explained in more detail below.
Create an interface in the .Core project which inherits from IRepository
. The reason this is created in the .Core project is so it can accessed by the rest of the solution
using Abp.Domain.Repositories;
namespace ExampleProject
{
public interface IEntityRepository : IRepository<Entity>
{
Entity DoSomething();
}
}
In your .EntityFrameworkCore project create a public class that implements your new repository interface.
public class EntityRepository
{
}
Inherit from EfCoreRepositoryBase
Below is the full listing:
using System.Data.Common;
using Abp.Data;
using Abp.EntityFrameworkCore;
using Abp.EntityFrameworkCore.Repositories;
using Microsoft.EntityFrameworkCore;
using SeeSayDo.Content;
namespace ExampleProject.EntityFrameworkCore.Repositories
{
public class EntityRepository : EfCoreRepositoryBase<ExampleProjectDbContext, Entity>, IEntityRepository
{
private readonly IDbContextProvider<ExampleProjectDbContext> contextProvider;
private readonly IActiveTransactionProvider transactionProvider;
public ContentPieceRepository(
IDbContextProvider<SeeSayDoDbContext> dbContextProvider,
IActiveTransactionProvider transactionProvider
) : base(dbContextProvider)
{
this.contextProvider = dbContextProvider;
this.transactionProvider = transactionProvider;
}
}
}
We still need to implement the function we defined in our interface that will call the stored procedure.
public Entity DoSomething()
{
var entity = new Entity();
using (var context = contextProvider.GetDbContext())
{
var connection = context.Database.GetDbConnection();
var command = connection.CreateCommand();
command.CommandText = "sp_DoSomething";
command.CommandType = System.Data.CommandType.StoredProcedure;
command.Transaction = (DbTransaction)transactionProvider.GetActiveTransaction(new ActiveTransactionProviderArgs
{
{"ContextType", typeof(ExampleProjectDbContext) },
{"MultiTenancySide", MultiTenancySide }
});
context.Database.OpenConnection();
using (var reader = command.ExecuteReader())
{
entity.Id = (int)reader["Id"];
...
}
}
return entity;
}
To use your custom repository, inject the interface into your application or domain service via the constructor and call your custom function. Because you inherited IRepository, all the other repository features are also available so you don't need to inject a generic repository as well as your custom one.
using System;
using Abp.Domain.Repositories;
using Abp.Domain.Services;
namespace ExampleProject.Entities
{
public class EntityManager : DomainService
{
private readonly IEntityRepository customRepository;
public EntityManager(
IContentPieceRepository customRepository
)
{
this.customRepository = customRepository;
}
public Entity DoSomething()
{
return contentRepository.DoSomething();
}
}
}
In the migration you can use SQL()
to add a script.
- ASP.NET Boilerplate Tutorials
- Adding Email Verification using SendGrid
- How to Update the Database