¿Cómo insertar datos y devolver la identidad insertada con Dapper en MVC?

asp.net-mvc c# dapper sql

Pregunta

Tengo un modelo de productos como este,

public int ProductID { get; set; }
public int ProductDetailsID { get; set; }
public int ProductStatusID { get; set; }
public string ProductName { get; set; }
public int Priority { get; set; }
public DateTime LastProcessedDate { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime ModifiedDate { get; set; }
public bool Enabled { get; set; }

Aquí está mi punto de vista,

@model MVCApplication1.Models.Products
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}
@using (Html.BeginForm())
{
<div class="form-horizontal">
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    @Html.HiddenFor(i => i.ProductDetailsID, new { @Value = ViewBag.ProductDetailsID })
    <div class="form-group">
        @Html.LabelFor(i => i.Name, "Product Name ", new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(i => i.Name, new { @class = "form-control" })
            @Html.ValidationMessageFor(i => i.Name, "", new { @class = "text-danger" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(i => i.Enabled, "Enabled ", new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.CheckBoxFor(i => i.Enabled, new { @class = "checkbox", @checked = "checked" })
            @Html.ValidationMessageFor(i => i.Enabled)
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
</div>
}

Aquí está mi controlador,

[HttpPost]
public ActionResult Create(Products model)
{
   try
   {
       if (ModelState.IsValid)
       {
           model.LastProcessedDate = DateTime.Now;
           model.CreatedDate = DateTime.Now;
           model.ModifiedDate = DateTime.Now;
           model.ProductStatusID = 0;
           int id = con.Query<int>("ProductInsert", model, commandType: CommandType.StoredProcedure).Single();

           return Content("Product added successfully..!!", "text/plain");
            }
        }
        catch (Exception)
        {
            throw;
        }
        return View();
 }

Y aquí está mi código sql,

CREATE PROCEDURE [dbo].[ProductCreate]
(
  @ProductDetailsId INTEGER,
  @ProductStatusID INTEGER,
  @ProductName VARCHAR(255),
  @Priority INTEGER,
  @LastProcessedDate DATETIME,
  @CreatedDate DATETIME,
  @ModifiedDate DATETIME,
  @Enabled BIT
)
AS
INSERT INTO dbo.Products (ProductDetailsId, ProductStatusId, Product, Priority, LastProcessedDate, CreatedDate, ModifiedDate, Enabled, ScheduleTypeId, Server, RetryNumber, Message) 
VALUES(@ProductDetailsId, @ProductStatusId, @ProductName, @Priority, @LastProcessedDate, @CreatedDate, @ModifiedDate, @Enabled)

SELECT SCOPE_IDENTITY() AS ProductID

Estoy obteniendo el error "procedimiento o función ProductCreate tiene demasiados argumentos especificados".

¿Qué estoy haciendo mal?

Respuesta experta

Cuando llama a un procedimiento almacenado, dapper no tiene una buena forma de saber qué miembros deberían tratarse como parámetros. Con tsql regular, puede tener una puñalada de "obviamente no usado", "obviamente usado", "tal vez", pero daptper no elige pagar el costo adicional de preguntarle a la base de datos cómo se ve el procedimiento almacenado todo el tiempo. Sospecho que está agregando propiedades que no se usan, ProductId en particular. Ayúdalo mapeando a un tipo anon. En lugar de pasar el model , pase:

new { model.ProductDetailsId, model.ProductStatusID, ...todo... ,
    model.Enabled }


Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué