AliAzra
AliAzra

Reputation: 919

Entity Framework Context is quite slow, not sure because of my coding or generally slow?

I found EF is quite slow to start. And wanted to know, because of my coding design or generally EF is slow.

I have got few tables

    public class ApplicationDbContext: DbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }
    public DbSet<ClientModel> ClientModels { get; set; }
    public DbSet<EmployeeModel> EmployeeModels { get; set; }
    public DbSet<ClientContactModel> ClientContactModels { get; set; }
    public DbSet<FileModel> FileModels { get; set; }
    ........
}

And I am using IRepository for each model. For examoke Client Model

 public interface IClientRepository
{
    IQueryable<ClientModel> ClientModel { get; }
    bool SaveClient(ClientViewModel client);
    bool DeleteClient(int? clientID);
}

 public class ClientRepository : IClientRepository
{
 constructor ...
 public IQueryable<ClientModel> ClientModel => context.ClientModels.OrderBy(c => c.ClientName);
}

In my Startup for each model

  services.AddTransient<IClientRepository, ClientRepository>();

And Finally my Controller i can access the data

private IClientRepository clientRepository;
private IEmployeeRepository employeeRepository;

public ClientController(IClientRepository _clientRepository, IEmployeeRepository _emp)
    {
        clientRepository = _clientRepository;
        employeeRepository = _emp;
    }

Is it the best way to get the data from database or shall i use context without interfaces- something like this

private readonly ApplicationDbContext context;
public ClientController(ApplicationDbContext cont)
    {
        context = cont;
    }

START UP

 public class Startup
{
    public IConfiguration Configuration { get; }
    public Startup(IConfiguration configuration) => Configuration = configuration;

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton(Configuration);
        services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration["ConnectionString1"]));
        services.AddDbContext<AppIdentityDbContext>(options => options.UseSqlServer(Configuration["ConnectionString2"]));
        services.AddDbContext<AppEmployeeDbContext>(options => options.UseSqlServer(Configuration["ConnectionString3"]));

        services.AddIdentity<IdentityUser, IdentityRole>().AddEntityFrameworkStores<AppIdentityDbContext>().AddDefaultTokenProviders();
        services.AddTransient<IClientRepository, ClientRepository>();
        services.AddTransient<IEmployeeRepository, EmployeeRepository>();
        services.AddTransient<IClientContactRepository, ClientContactRepository>();
        services.AddTransient<IFileRepository, FileRepository>();
        services.AddTransient<IDolsMcaClientRepository, DolsMcaClientRepository>();
        services.AddTransient<IDolsMcaItemRepository, DolsMcaItemRepository>();
        services.AddTransient<IMcaRepository, McaRepository>();
        services.AddTransient<IIncidentRepository, IncidentRepository>();



        services.AddMvc();
        services.AddSession(options =>
        {
            options.IdleTimeout = TimeSpan.FromSeconds(1000 * 60 * 60); //1hr
            options.Cookie.HttpOnly = true;
            options.Cookie.IsEssential = true;
        });
    }


    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseStaticFiles();
        app.UseStatusCodePages();
        app.UseSession();
        app.UseAuthentication();


        app.UseMvc(routes => {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
        }
        else
        {
            app.UseExceptionHandler("/Error/500");
            app.UseStatusCodePagesWithReExecute("/Error/{0}");
        }

        app.Run(async (context) =>
        {
            await context.Response.WriteAsync("Empty!");
        });
    }
}

Upvotes: 0

Views: 1028

Answers (1)

GoldenAge
GoldenAge

Reputation: 3068

I found EF is quite slow to start. And wanted to know, because of my coding design or generally EF is slow.

  1. First of all, if you are using Entity Framework Core you don't need to create extra Repository layer as EF Core is a repository by itself. Instead of creating extra Repository classes and IRepository interfaces you can create extension methods for your entities and inject the ApplicationDbContext directly to your services. You can have a look at what is the idea of this approach here

  2. When you know that you only read the data in the given scope you can use lazy loading to improve the speed of your queries. This can give you a big performance boost. Check also how AsNoTracking thingy works to improve the performance

  3. Avoid things like this context.ClientModels.OrderBy(c => c.ClientName); as it results in select * from ... which is quite common problem. I know that in your case you are using the IQueryable so you can add some more logic to the query, however, creating an extra field to just only invoke the OrderBy on seems like a triumph of form over content.

  4. Use Async methods as EF Core allows you to do this.

  5. If you are saying that Entity Framework is slow maybe think more about the system architecture as in the case where you have to deal with millions of records in your DB you can think about changing approach and denormalized your DB to avoid complex JOIN queries as it always has a big impact on the performance when dealing with big data.

Upvotes: 1

Related Questions