从ASP.Net Razor Pages中的.cshtml页面链接到存储过程结果集

问题描述 投票:1回答:2

我想看某种媒体类型的电影(即DVD,Bluray,VHS),所以我创建了存储过程来做到这一点。此存储过程返回具有与媒体类型关联的ID的影片。例如,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. 这是我的媒体详细信息.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 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。任何帮助将不胜感激。

asp.net tsql stored-procedures razor razor-pages
2个回答
1
投票

根据您的意见:

您需要首先通过引入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
投票

以下代码对我有用。 Izzy的回复非常有帮助,但需要进行一些调整。

我的数据访问层

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

            }
        }
    }
}

我的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>


推荐问答
热门问答
最新问答