.NET 6, EF + Dapper

0

Chciałbym używać EF dla operacji wsadowych głównie natomiast odczytywać Dapper`em - będę miał sporo skomplikowanych select'ów i wolę je napisać z palca.
Chciałbym Was zapytać czy mój zaczątek kodu jest w porządku i czy wybrać jedną wersję czy drugą i czy coś mnie w tym wszystkim później nie spierze po tyłku, nie skłócą się połączenia używane z Dapperem i EF?

mój Program.cs

var builder = WebApplication.CreateBuilder(args);

// tutaj mam konfig JWT pomijam ...

// Add services to the container.

builder.Services.AddControllers().AddFluentValidation();
builder.Services.AddDbContext<SalesManagerDbContext>();
builder.Services.AddScoped<ICustomerRepository, CustomerRepository>();
builder.Services.AddScoped<IAccountService, AccountService>();
builder.Services.AddScoped<IPasswordHasher<User>, PasswordHasher<User>>();
builder.Services.AddScoped<IValidator<RegisterUserDto>, RegisterUserDtoValidator>();
builder.Services.AddScoped<ErrorHandlingMiddleware>();
builder.Services.AddTransient<IDbConnection>((sp) => new SqlConnection(builder.Configuration.GetConnectionString("default")));

var app = builder.Build();

// Configure the HTTP request pipeline.
app.UseMiddleware<ErrorHandlingMiddleware>();
app.UseAuthentication();
app.UseHttpsRedirection();

app.MapControllers();

app.Run();

Przykładowe repozytorium

public class CustomerRepository : ICustomerRepository
{
    private readonly IConfiguration _configuration;
    private readonly IDbConnection _dbConnection;

    public CustomerRepository(IConfiguration configuration, IDbConnection dbConnection)
    {
        _configuration = configuration;
        _dbConnection = dbConnection;
    }
    public IEnumerable<Customer> GetCustomers()
    {          
        using (IDbConnection connection = new SqlConnection(_configuration.GetConnectionString("default")))
        {
            connection.Open();
            var result = connection.Query<Customer>(Querries.Customers);

            return result.ToList();
        }
    }
    public IEnumerable<Customer> GetCustomersBySalesRepresentative(int id)
    {          
        return _dbConnection.Query<Customer>(Querries.CustomersBySalesRepresentative, new { p_salesRepresentative = id });
    }
}
  1. czy lepiej i z jakich ewentualnie względów używać "sposobu" z metody GetCustomers() czy GetCustomersBySalesRepresentative() ?
  2. czy w ogóle w Program.cs zrobiłem dobrą konfigurację i czy dobrze użyłem tego w repozytorium. Czy może również użyć using w GetCustomersBySalesRepresentative()? W netach doczytałem, że Dapper will automatically open, close and dispose the connection for you.
builder.Services.AddTransient<IDbConnection>((sp) => new SqlConnection(builder.Configuration.GetConnectionString("default")));
  1. Aplikacja nie będzie jakaś mega skomplikowana, gro operacji to read, czy w taki sposób używanie EF + Dapper jest OK?
  2. Pytanie dodatkowe. Aplikacja będzie się komunikowała z dwoma db na tym samym serwerze SQL. Baza aplikacji oraz baza jakiegoś ERP ( będą wystawione widoki, tutaj tylko Dapper ). Chcę zrobić tak, że mam jeden connectionString do bazy aplikacji z userem, który ma full prawa do bazy aplikacji oraz prawa read ( być może tylko do widoków dedykowanych, nie wykluczam też, że read z jakiś tabel również ) do bazy ERP. Co sądzicie o takim podejściu? Wtedy Dapperem query zapodałbym w stylu "select * from bazaerp.schema.widok"
  3. I ostatnie, zapytania sql ... zapakowałem np.
public class Querries
{
    public static string CustomersBySalesRepresentative = @"select ....";
    //...

czy jak takie rzeczy robicie? wydaję się to dość czyste rozwiązanie

1
john_doe napisał(a):
  1. czy lepiej i z jakich ewentualnie względów używać "sposobu" z metody GetCustomers() czy GetCustomersBySalesRepresentative() ?\

No ja nie rozumiem GetCustomers - po co tworzyć samemu SqlConnection, skoro dostajemy je wstrzyknięte przez konstruktor?

  1. Aplikacja nie będzie jakaś mega skomplikowana, gro operacji to read, czy w taki sposób używanie EF + Dapper jest OK?

Nie wiem. Ale to, że robisz wrapper na Dapper, nie znaczy od razu, że masz repozytorium.

  1. Pytanie dodatkowe. Aplikacja będzie się komunikowała z dwoma db na tym samym serwerze SQL. Baza aplikacji oraz baza jakiegoś ERP ( będą wystawione widoki, tutaj tylko Dapper ). Chcę zrobić tak, że mam jeden connectionString do bazy aplikacji z userem, który ma full prawa do bazy aplikacji oraz prawa read ( być może tylko do widoków dedykowanych, nie wykluczam też, że read z jakiś tabel również ) do bazy ERP. Co sądzicie o takim podejściu? Wtedy Dapperem query zapodałbym w stylu "select * from bazaerp.schema.widok"

No to chyba nieuniknione jeśli masz dwie bazy.

  1. I ostatnie, zapytania sql ... zapakowałem np.
public class Querries
{
    public static string CustomersBySalesRepresentative = @"select ....";
    //...

czy jak takie rzeczy robicie? wydaję się to dość czyste rozwiązanie

A co to daje? Bo jak jest w tym samej klasie co "repozytorium", to przynajmniej nie trzeba skakać po plikach. A wepchnięcie wszystkich stałych z całej aplikacji w jedno miejsce w czym pomoże?

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.