Как передать context в класс ASP.NET MVC CORE

162
20 октября 2019, 08:20

Не могу разобраться, как все таки правильно, с контроллера передавать данные из БД в класс или все таки в классе получать доступ к БД? Например: Мой класс:

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; }
 }

Мой контекст:

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

И вот я реализую класс, который производит сортировку, и я бы хотел что бы он получал данные из бд, сортировал их и складывал в коллекции, а потом возвращал мне эти коллекции.

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;
    }
}

Только я не понимаю, как сделать так, что бы класс мог обращаться к базе данных? Или я должен передать в данный класс данные из БД через контроллер? Т.Е. в контроллере получить всю БД, положить ее в коллекцию и передать эту коллекцию классу? Как правильно должно это реализовываться в ASP.NET? Было бы хорошо примером реальным, потому что во всех учебниках, которые я видел, вся логика реализуется в контроллере.

Answer 1

В самом простом варианте вы должны в своём классе указать, что вашему классу требуется контекст:

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;
    }

Поскольку у вас проект asp.net core — то в Startup.cs уже настроен проброс контекста во все нужные классы.

Собственно на контроллеры будете передавать ваш класс RssFeedsRepository на конструктор, тут лучше объявить интерфейс:

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

PS А когда/если вам надоест писать однотипный код — используйте антипаттерн generic repository, вынеся всю однообразную логику в интерфейсы. Пример по ссылке, которую вам дал @Bulson в комментариях.

Неподскажите, какая строчка в startup отвечает за это?

Вот типовой файл, который генерирует студия:

    // 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);
    }

Это проект в котором поставлена галка использовать identity, в нём уже сразу настроен доступ к базе. В строке с services.AddDbContext происходит создание контекста с дефолтным connection string.

А вот регистрацию репозиториев нужно будет настраивать - в самом простом варианте каждый вручную:

services.AddTransient<IRssFeedsRepository, RssFeedsRepository>();

Либо регистрируя одним махом:

        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);
            }
        }

Либо используя ваш любимый (подставить название) DI фреймворк.

READ ALSO
Как достать объекты из БД и занести их в picker

Как достать объекты из БД и занести их в picker

Чтобы, при выборе в нём, они заносились в новый список, чтобы произвести с ними расчётыЗаранее благодарю за помощь

151
Авторизация с __RequestVerificationToken и cookie

Авторизация с __RequestVerificationToken и cookie

Пытаюсь написать программу для парсинга неких данных с сайта, с парсингом проблем быть не должно, но от авторизации уже голова болитНе пойму...

214
Перенос кода из java на c#

Перенос кода из java на c#

Как получить байтовый массив из запросаНапример есть следующий код на java:

131