【问题标题】:Using stored procedure in ASP.NET MVC在 ASP.NET MVC 中使用存储过程
【发布时间】:2017-12-28 13:24:08
【问题描述】:

我对在我的 mvc 应用程序中使用存储过程非常陌生,因此我将不胜感激有关以下问题的任何指导。

目的: 我有一个返回礼品卡余额的存储过程。基本上,当用户输入卡号时,它会返回该卡的所有相关详细信息。问题是我不知道如何在我的 MVC 应用程序上完成这项工作。

到目前为止我尝试了什么: 上下文类:

public virtual ObjectResult<string> GetBalance(string cardNumber)
    {
        var cardNumberParameter = cardNumber != null ?
            new ObjectParameter("CardNumber", cardNumber) :
            new ObjectParameter("CardNumber", typeof(string));

        return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<string>("GetBalance", cardNumberParameter);
    }

控制器:

    [HttpPost]
    public ActionResult GetBalance(string cardNumber)
    {

        var balance = db.GetBalance(cardNumber).ToList();

        return View("GetBalance");

    }

观点:

@using (Html.BeginForm("GetBalance", "Cards", FormMethod.Post))
                        {
                            @Html.AntiForgeryToken()
                            <div class="panel-body">
                                <div class="row">
                                    <div class="col-lg-12">
                                        <form role="form">
                                            @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                                           
                                               
                                           
                                            <div class="form-group">
                                                Number of Cards: <input type="text" name="cardNumber"/>
                                            </div>
                                            

                                            <input type="submit" value="Create" class="btn btn-default" style="background-color: #0a9dbd; color: white;" />
                                            <button type="reset" class="btn btn-default" style="background-color: #0a9dbd; color: white;">Reset</button>

                                            <div>
                                                @Html.ActionLink("Back to List", "Index")
                                            </div>
                                        </form>
                                    </div>

                                </div>
                            </div>
                        }

存储过程

    GO

ALTER PROCEDURE  [dbo].[GetBalance]
-- Add the parameters for the stored procedure here
@CardNumber nvarchar(20)
AS
BEGIN

SET NOCOUNT ON;
If Not Exists(Select CardID From Cards With (NOLOCK) Where CardNumber = @CardNumber OR (Cards.CardNumber2 = @CardNumber))
Begin
Select 'Invalid Card Number' as Error
END

Select Sum(TotalAmount) as TotalAmount, StoreCustomerName, StoreCustomerISurname, StoreCustomerEmail, StoreCustomerDOB, StoreCustomerAddress, StoreCustomerCity, 
                         StoreCustomerRegion, StoreCustomerCountry, StoreCustomerCel, StoreCustomerDate, StoreCustomerToken, '' as Error, StoreCustomerID, CardNumber, CardStatus,
                         LoyaltyLevelName, LoyaltyLevel, DiscountLevelAmount, DiscountLevelName, GiftCardEnabled, LoyaltyEnabled, StoreCustomerNumber From (
SELECT        0 AS TotalAmount, StoreCustomers.StoreCustomerName, StoreCustomers.StoreCustomerISurname, StoreCustomers.StoreCustomerEmail, StoreCustomers.StoreCustomerDOB, StoreCustomers.StoreCustomerAddress, StoreCustomers.StoreCustomerCity, 
                         StoreCustomers.StoreCustomerRegion, StoreCustomers.StoreCustomerCountry, StoreCustomers.StoreCustomerCel, StoreCustomers.StoreCustomerDate, StoreCustomers.StoreCustomerToken, StoreCustomers.StoreCustomerID, 
                         Cards.CardNumber, Cards.CardStatus, LoyaltyLevels.LoyaltyLevelName, LoyaltyLevels.LoyaltyLevel, DiscountLevels.DiscountLevelAmount, DiscountLevels.DiscountLevelName, Cards.GiftCardEnabled, Cards.LoyaltyEnabled, StoreCustomerNumber
FROM            StoreCustomers WITH (NOLOCK) INNER JOIN
                         Cards WITH (NOLOCK) ON StoreCustomers.StoreCustomerID = Cards.StoreCustomerID INNER JOIN
                         DiscountLevels WITH (NOLOCK) ON Cards.DiscountLevelID = DiscountLevels.DiscountLevelID AND Cards.CustomerID = DiscountLevels.CustomerID  INNER JOIN 
                         LoyaltyLevels WITH (NOLOCK) ON Cards.LoyaltyLevelID = LoyaltyLevels.LoyaltyLevelID AND Cards.CustomerID = LoyaltyLevels.CustomerID
WHERE         (Cards.CardNumber = @CardNumber) OR (Cards.CardNumber2 = @CardNumber) --WHERE        (Cards.CardID = @CardID)
GROUP BY StoreCustomers.StoreCustomerName, StoreCustomers.StoreCustomerISurname, StoreCustomers.StoreCustomerEmail, StoreCustomers.StoreCustomerDOB, StoreCustomers.StoreCustomerAddress, StoreCustomers.StoreCustomerCity, 
                         StoreCustomers.StoreCustomerRegion, StoreCustomers.StoreCustomerCountry, StoreCustomers.StoreCustomerCel, StoreCustomers.StoreCustomerDate, StoreCustomers.StoreCustomerToken, StoreCustomers.StoreCustomerID, 
                         Cards.CardNumber, Cards.CardStatus, LoyaltyLevels.LoyaltyLevelName, LoyaltyLevels.LoyaltyLevel, DiscountLevels.DiscountLevelAmount, DiscountLevels.DiscountLevelName,Cards.GiftCardEnabled, Cards.LoyaltyEnabled, StoreCustomerNumber
Union ALL
SELECT        SUM(Sales.SaleTotalAmount) AS TotalAmount, StoreCustomers.StoreCustomerName, StoreCustomers.StoreCustomerISurname, StoreCustomers.StoreCustomerEmail, StoreCustomers.StoreCustomerDOB, StoreCustomers.StoreCustomerAddress,
                         StoreCustomers.StoreCustomerCity, StoreCustomers.StoreCustomerRegion, StoreCustomers.StoreCustomerCountry, StoreCustomers.StoreCustomerCel, StoreCustomers.StoreCustomerDate, 
                         StoreCustomers.StoreCustomerToken, StoreCustomers.StoreCustomerID, Cards.CardNumber, Cards.CardStatus, LoyaltyLevels.LoyaltyLevelName, LoyaltyLevels.LoyaltyLevel, DiscountLevels.DiscountLevelAmount, 
                         DiscountLevels.DiscountLevelName, Cards.GiftCardEnabled, Cards.LoyaltyEnabled, StoreCustomerNumber
FROM            StoreCustomers WITH (NOLOCK) INNER JOIN
                         Cards WITH (NOLOCK) ON StoreCustomers.StoreCustomerID = Cards.StoreCustomerID INNER JOIN
                         Sales WITH (NOLOCK) ON Cards.CardID = Sales.CardID INNER JOIN
                         LoyaltyLevels WITH (NOLOCK) ON Cards.LoyaltyLevelID = LoyaltyLevels.LoyaltyLevelID AND Cards.CustomerID = LoyaltyLevels.CustomerID  INNER JOIN
                         DiscountLevels WITH (NOLOCK) ON Cards.DiscountLevelID = DiscountLevels.DiscountLevelID AND Cards.CustomerID = DiscountLevels.CustomerID
WHERE         (Cards.CardNumber = @CardNumber) OR (Cards.CardNumber2 = @CardNumber)--WHERE        (Cards.CardID = @CardID)
GROUP BY StoreCustomers.StoreCustomerName, StoreCustomers.StoreCustomerISurname, StoreCustomers.StoreCustomerEmail, StoreCustomers.StoreCustomerDOB, StoreCustomers.StoreCustomerAddress, StoreCustomers.StoreCustomerCity, 
                         StoreCustomers.StoreCustomerRegion, StoreCustomers.StoreCustomerCountry, StoreCustomers.StoreCustomerCel, StoreCustomers.StoreCustomerDate, StoreCustomers.StoreCustomerToken, StoreCustomers.StoreCustomerID, 
                         Cards.CardNumber, Cards.CardStatus, LoyaltyLevels.LoyaltyLevelName, LoyaltyLevels.LoyaltyLevel, DiscountLevels.DiscountLevelAmount, DiscountLevels.DiscountLevelName, Cards.GiftCardEnabled, Cards.LoyaltyEnabled, StoreCustomerNumber

) as x
GROUP BY StoreCustomerName, StoreCustomerISurname, StoreCustomerEmail, StoreCustomerDOB, StoreCustomerAddress, StoreCustomerCity, StoreCustomerRegion, StoreCustomerCountry, StoreCustomerCel, StoreCustomerDate, StoreCustomerToken, StoreCustomerID, 
CardNumber, CardStatus, LoyaltyLevelName, LoyaltyLevel, DiscountLevelAmount, DiscountLevelName, GiftCardEnabled, LoyaltyEnabled, StoreCustomerNumber

END

【问题讨论】:

  • 我这样做了,但没用。我确实发布了我尝试过的内容。也许告诉我我应该在那里改变什么?
  • 什么不起作用?它有没有抛出任何异常?如果是这样,请发布堆栈跟踪。如果不是,请解释什么不起作用。
  • 没有用是什么意思?你看到什么错误了吗?意外输出?
  • 错误:“/”应用程序中的服务器错误。无法找到该资源。说明:HTTP 404。您要查找的资源(或其依赖项之一)可能已被删除、名称已更改或暂时不可用。请查看以下 URL 并确保其拼写正确。请求的 URL:/Cards/GetBalance
  • 这不是 sql server 错误。你什么时候收到这个错误?您是否为此配置了正确的路线?

标签: c# sql stored-procedures model-view-controller ef-database-first


【解决方案1】:

您在控制器中为GetBalance 显示的唯一方法是用HttpPost 属性修饰的,这意味着它只会响应通过POST 发出的请求,即通过提交表单发出的请求您在GetBalance 视图中显示的,目前无法访问。

您可以做的一件事是提供两个独立的控制器方法:

public ActionResult GetBalance()
{
    return View();
}

[HttpPost]
public ActionResult GetBalance(string cardNumber)
{
    // Do stuff to retrieve the balance here
    return View("GetBalance");
}

注意第一个GetBalance 方法有:

  • 没有装饰它的属性,因此它响应 GET 请求(例如来自 /Index 页面上的链接/按钮的请求)
  • 没有明确命名它想要返回的视图 - 这是因为视图的名称隐含在 Action 的名称中,从而可以编写更清晰的代码。

【讨论】:

  • 天哪,不知道我是怎么错过的。这摆脱了那个错误。谢谢:)
  • 我现在收到此错误:数据读取器与指定的“GiftorxModel.Card”不兼容。类型的成员“CardID”在数据读取器中没有同名的对应列。知道如何解决这个问题
  • @Janine,这是一个完全不同的问题,会有一个非常不同的答案。在stackoverflow上遵循“每个问题一个问题”模型,所以请继续就您现在遇到的问题提出另一个问题,以及重新创建它的最少代码=)很高兴我的回答对您的第一个问题有所帮助! =)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-27
  • 2020-02-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多