Ссылка на набор результатов хранимой процедуры со страницы .cshtml в ASP.Net Razor Pages - PullRequest
1 голос
/ 15 апреля 2019

Я хочу смотреть фильмы определенного типа (например, DVD, Bluray, VHS), поэтому я создал хранимую процедуру для этого. Эта хранимая процедура возвращает фильмы с идентификатором, связанным с типом носителя. Например, ID 1 возвращает DVD. У меня есть страница для моего типа мультимедиа со списком мультимедиа (бритвенные страницы автоматически создавали для меня страницу сведений после лесов).

  1. У меня есть код для моей хранимой процедуры ниже:
using System;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Movies.Models
{
    public class MovieDataAccessLayer
    {
        string connectionString = "Server=ServerName;Database=DatabaseMovies;Trusted_Connection=True;MultipleActiveResultSets=true";

        public IEnumerable<Movies> MovieByMedia(byte? MediaID)
        {
            List<Movies> lstmovie = new List<Movies>();

            using (SqlConnection con = new SqlConnection(connectionString))
            {
                SqlCommand cmd = new SqlCommand("usp_MovieByMedia", con);
                cmd.CommandType = CommandType.StoredProcedure;

                con.Open();
                SqlDataReader rdr = cmd.ExecuteReader();

                while (rdr.Read())
                {
                    Movies movies = new Movies();

                    movies.MovieTitle = rdr["MovieTitle"].ToString();
                    movies.MovieYear = Convert.ToInt32(rdr["MovieYear"]);

                    lstmovie.Add(movies);
                }

                con.Close();

            }
            return lstmovie;
        }

    }
}

  1. Вот мой Media Details .cshtml.cs code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using Movies.Models;

namespace Movies.Pages.MediaDetails
{
    public class DetailsModel : PageModel
    {
        private readonly Movies.Models.MoviesContext _context;

        public DetailsModel(Movies.Models.MoviesContext context)
        {
            _context = context;
        }

        public Media Media { get; set; }

        public async Task<IActionResult> OnGetAsync(byte? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            Media = await _context.Media.FirstOrDefaultAsync(m => m.MediaTypeID == id);


            if (Media == null)
            {
                return NotFound();
            }
            return Page();
        }
    }
}
  1. А вот и моя страница .cshtml
@model Movies.Pages.MediaDetails.DetailsModel

@{
    ViewData["Title"] = "Details";
}

<h1>Details</h1>

<div>
    <h4>Media</h4>
    <hr />
    <dl class="row">
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Media.MediaType)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Media.MediaType)
        </dd>
    </dl>
</div>
<div>
    <a asp-page="./Edit" asp-route-id="@Model.Media.MediaTypeID">Edit</a> |
    <a asp-page="./Index">Back to List</a>
</div>
  1. Вот код сведений о моем фильме .cshtml, который я безуспешно пытался подключить к своему медиа .cshtml
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using Movies.Models;

namespace Movies.Pages.MovieDetails
{
    public class DetailsModel : PageModel
    {
        private readonly Movies.Models.MoviesContext _context;

        public DetailsModel(Movies.Models.MoviesContext context)
        {
            _context = context;
        }

        MovieDataAccessLayer objmovie = new MovieDataAccessLayer();
        public Movies 
            Movies { get; set; }

        public async Task<IActionResult> OnGetAsync(byte id)
        {
            Movies = await _context.Movies.FirstOrDefaultAsync(m => m.MediaTypeID == id);

            if (Movies == null)
            {
                return NotFound();
            }
            return Page();
        }
    }
}

Я хотел бы изменить свою страницу сведений, которая перечисляет мои типы мультимедиа, чтобы при нажатии «подробности» для соответствующего типа мультимедиа я мог сгенерировать результат моей хранимой процедуры для типа мультимедиа, на который я нажимаю. Например, когда я нажимаю «DVD», моя хранимая процедура выполняется, чтобы показать мне только мои DVD. Как мне это сделать? Я знаю, что мне нужно как-то обратиться к слою доступа к данным фильма, чтобы выполнить мой SP. Любая помощь будет принята с благодарностью.

Ответы [ 2 ]

1 голос
/ 15 апреля 2019

Основано на ваших комментариях:

Сначала вам нужно будет внести изменения в вашу хранимую процедуру, введя предложение where и приняв параметр в.

ALTER PROCEDURE usp_MovieByMedia
    @MediaID INT //This is the parameter we will accept in the stored procedure which will be passed via our c# code
    SELECT MovieTitle, MovieYear 
    FROM MOVIES 
    WHERE MediaTypeID = @MediaID   // I'm assuming the names here, change as required

Теперь вы хотите изменить свой метод следующим образом:

public Movies GetMovieByMedia(int MediaID)
{
   string connectionString = "Server=ServerName;Database=DatabaseMovies;Trusted_Connection=True;MultipleActiveResultSets=true";
   var movies = new Movies();

   using (var con = new SqlConnection(connectionString))
   {
     using (var cmd = new SqlCommand("usp_MovieByMedia", con))
     {
        cmd.Parameters.Add(new SqlParameter("@MediaID", SqlDbType.Int) { Value = MediaID }); //you was missing this.
        cmd.CommandType = CommandType.StoredProcedure;
        con.Open();

        using (var reader = cmd.ExecuteReader())
        {
           if (reader.HasRows)
           {
              movies.MovieTitle = reader["MovieTitle"].ToString();
              movies.MovieYear = Convert.ToInt32(reader["MovieYear"]);
           }
         }
      }
    }
    return movies;
 }

Это вернет вам один объект Movie.

Обратите внимание, я предположил, что ваш столбец MediaTypeID имеет тип INT в БД, а не varbinary(1)/binary(1). Если это неправильно, измените как требуется.

Теперь в вашем OnGetAsync действии вы можете сделать:

Movies = objmovie.GetMovieByMedia(id);

Если вы не хотите выполнять фильтрацию в базе данных, вы можете использовать linq для фильтрации в вашем приложении как:

Movies = objmovie.GetMovieByMedia(id).FirstOrDefault(i => i.MediaTypeID == id); //this will only work if your method stays with the return type of IEnumerable<Movies>
0 голосов
/ 28 апреля 2019

Следующий код работал для меня. Ответ Иззи был очень полезным, но нужно было кое-что исправить.

Мой уровень доступа к данным

using System;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace MyMovies.Models
{
    public class MovieByMediaDataAccessLayer
    {
        public List<Movies> GetMovieByMedia(byte? MediaID)
        {
            string connectionString = "Server=Servername;Database=Movies;Trusted_Connection=True;MultipleActiveResultSets=true";
            var movies = new Movies();
            using (var con = new SqlConnection(connectionString))
            {
                using (var cmd = new SqlCommand("usp_MovieByMedia", con))
                {
                    cmd.Parameters.Add(new SqlParameter("@MediaID", SqlDbType.TinyInt) { Value = MediaID });
                    cmd.CommandType = CommandType.StoredProcedure;
                    con.Open();

                    using (var reader = cmd.ExecuteReader())
                    {
                        List<Movies> Movies = new List<Movies>();
                        while (reader.Read())
                        {
                            Movies movie = new Movies()
                            {
                                MovieTitle = reader["MovieTitle"].ToString(),
                                MovieYear = Convert.ToInt32(reader["MovieYear"])
                            };
                            Movies.Add(movie);
                        }
                        return Movies;
                    }
                }

            }
        }
    }
}

Класс My Details, в который я возвращаю все фильмы, выполненные из хранимой процедуры (файл .cshtml.cs)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using MyMovies.Models;

namespace MyMovies.Pages.MovieDetails
{
    public class DetailsModel : PageModel
    {
        private readonly MyMovies.Models.MyMoviesContext _context;

        public DetailsModel(MyMovies.Models.MyMoviesContext context)
        {
            _context = context;
        }



        MovieByMediaDataAccessLayer objmovie = new MovieByMediaDataAccessLayer();

        public List<Movies> Movies { get; set; }


        public async Task<IActionResult> OnGetAsync(byte? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            Movies = objmovie.GetMovieByMedia(id);
            if (Movies == null)
            {
                return NotFound();
            }
            return Page();
        }
    }
}

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

@page
@model MyMovies.Pages.MovieDetails.DetailsModel

@{
    ViewData["Title"] = "Details";
}

<h4>Movies</h4>
<hr />
<div>
    <table>
        <tr>
            <th>Movie Title</th>
            <th>Movie Year</th>
        </tr>
        @foreach (var item in Model.Movies)
        {
            <tr>
                <td class="col-sm-10">
                    @Html.DisplayFor(Model => item.MovieTitle)
                </td>
                <td class="col-sm-10">
                    @Html.DisplayFor(Model => item.MovieYear)
                </td>
            </tr>
        }
    </table>
</div>

<div>
    <a asp-page="./Index">Back to List</a>
</div>


...