I can not figure out how everything is correct, from the controller to transfer data from the database to the class or still in the class to get access to the database? For example: My class:

public class RssFeeds { [Key] public int RssFeedsId { get; set; } public string Indeficator { get; set; } [Display(Name = "Источник" )] public string Source { get; set; } [Display(Name = "Название новости")] public string TitleNew { get; set; } [Display(Name = "Описание новости")] public string News { get; set; } [Display(Name = "Дата публикации")] public string Date { get; set; } } 

My context:

 public class DataBaseContext : DbContext { public DataBaseContext(DbContextOptions<DataBaseContext> options) : base(options) { } public virtual DbSet<RssFeeds> RssFeeds { get; set; } } 

And here I am implementing a class that performs sorting, and I would like it to get data from the database, sort it and put it in the collection, and then return these collections to me.

 public class Sorted : ISorted { public List<RssFeeds> getSortDateHabr() { List<RssFeeds> list = db.RssFeeds.OrderBy(p => p.Date).Where(m => m.Indeficator == "H").ToList(); return list; } public List<RssFeeds> getSortDateInterFax() { List<RssFeeds> list = db.RssFeeds.OrderBy(p => p.Date).Where(m => m.Indeficator == "I").ToList(); return list; } public List<RssFeeds> getSortSourceHabr() { List<RssFeeds> list = db.RssFeeds.OrderBy(p => p.Source).Where(m => m.Indeficator == "H").ToList(); return list; } public List<RssFeeds> getSortSourceInterFax() { List<RssFeeds> list = db.RssFeeds.OrderBy(p => p.Source).Where(m => m.Indeficator == "I").ToList(); return list; } public List<RssFeeds> getSortSDateAll() { List<RssFeeds> list = db.RssFeeds.OrderBy(p => p.Date).ToList(); return list; } public List<RssFeeds> getSortSourceAll() { List<RssFeeds> list = db.RssFeeds.OrderBy(p => p.Source).ToList(); return list; } } 

Only I do not understand how to make it so that the class could access the database? Or should I transfer the data from the database through the controller to this class? THOSE. in the controller, get the entire database, put it into the collection and transfer this collection to the class? How should this be implemented correctly in ASP.NET? It would be a good example of a real one, because in all the textbooks that I saw, all the logic is implemented in the controller.

  • one
    You need to implement the patterns "Repository" and "Unit of Work". In good tutorials it should be. See here . - Bulson

1 answer 1

In its simplest form, you should indicate in your class that your class needs a context:

 public class RssFeedsRepository { public RssFeedsRepository(DataBaseContext dbContext) { this.Context = dbContext; } private DataBaseContext Context { get; } public List<RssFeeds> getSortDateHabr() { List<RssFeeds> list = Context.RssFeeds.OrderBy(p => p.Date).Where(m => m.Indeficator == "H").ToList(); return list; } 

Since you have an asp.net core project, Startup.cs has already configured context forwarding to all the necessary classes.

Actually, the controllers will transfer your RssFeedsRepository class to the constructor, it is better to declare the interface:

 public class RssFeedsController { public RssFeedsController(IRssFeedsRepository RssFeedsRepository) { this.RssFeedsRepository = RssFeedsRepository; } private IRssFeedsRepository RssFeedsRepository{ get; } 

PS And when / if you get tired of writing the same type of code - use the generic repository antipattern, bringing all the same logic to the interfaces. An example of a link given to you by @Bulson in the comments.

Could you tell me which line in startup is responsible for this?

Here is the sample file that the studio generates:

  // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { // This lambda determines whether user consent for non-essential cookies is needed for a given request. options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer( Configuration.GetConnectionString("DefaultConnection"))); services.AddDefaultIdentity<IdentityUser>() .AddDefaultUI(UIFramework.Bootstrap4) .AddEntityFrameworkStores<ApplicationDbContext>(); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); } 

This is a project in which the daw is set to use identity, it is already immediately configured to access the database. In the line with services.AddDbContext , a context is created with the default connection string.

But the registration of the repositories will need to be configured - in the simplest version, each manually:

 services.AddTransient<IRssFeedsRepository, RssFeedsRepository>(); 

Or registering in one fell swoop:

  var svcAssembly = Assembly.GetAssembly(typeof(ContactServiceBase)); var allSvc = svcAssembly.GetTypes().Where(p => p.GetTypeInfo().IsClass && p.Name.Contains("Service") && !p.GetTypeInfo().IsAbstract); foreach (var type in allSvc) { var allInterfaces = type.GetInterfaces(); var mainInterfaces = allInterfaces.Except(allInterfaces.SelectMany(t => t.GetInterfaces())); foreach (var itype in mainInterfaces) { services.AddTransient(itype, type); } } 

Or using your favorite (substitute the name) DI framework.

  • Since you have an asp.net core project, Startup.cs has already configured context forwarding to all the necessary classes. Could you tell me which line in startup is responsible for this? - Dmitry
  • @ Dmitry I added the answer. - AK