簡體   English   中英

無法使用映射的存儲過程插入數據庫

[英]Can't Insert to Database with Mapped Stored Procedure

我正在使用Entity Framework 6代碼優先方法,並且具有以下操作控制器方法來插入主從條目:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create( Facturas_prueba facturas_prueba, List<FacturasDetalle_prueba> detalle)
{
    if (detalle != null && detalle.Count > 0 ) {
        for (int i = 0; i <= detalle.Count-1; i++) {
            detalle[i].folio = facturas_prueba.folio;

        ModelState["detalle[" + i + "].folio"].Errors.Clear(); //Elimina los errores de validaciones del modelo porque ya asignamos manualmente el folio
    }
}
else
{
    ModelState.AddModelError("folio", "No asignó ningun detalle para el folio"); //Agrega un error de modelo al diccionario de ModelState
}

if (ModelState.IsValid) //Si el estado del model es valido (Todas las validaciones correctas)
{
    db.Database.Log = Logger;
    db.Facturas_prueba.Add(facturas_prueba);
    db.FacturasDetalle_prueba.AddRange(detalle); //AddRange sirve para agregar collecciones
    db.SaveChanges();
    return RedirectToAction("Index");
}

ViewBag.almacen = new SelectList(db.CATALMA, "COD_ALM", "NOM_ALM", facturas_prueba.almacen);
ViewBag.cliente = new SelectList(db.CATCTES, "COD_CTE", "NOM_CTE", facturas_prueba.cliente);
ViewBag.usuario = new SelectList(db.FACPARU, "cod_usu", "cod_Alm", facturas_prueba.usuario);
ViewBag.plaza = new SelectList(db.PLAZAS, "PLAZA", "LAST_COD_CTE", facturas_prueba.plaza);
return View(facturas_prueba);

這通常在使用默認的EF方式時有效,但是,現在,我嘗試使用存儲過程在每個表中插入(僅此刻),在db.SaveChanges()處出現異常:

用戶代碼未處理System.Data.Entity.Infrastructure.DbUpdateConcurrencyException

存儲更新,插入或刪除語句影響了意外的行數(0)。 自加載實體以來,實體可能已被修改或刪除。 有關了解和處理樂觀並發異常的信息,請參見http://go.microsoft.com/fwlink/?LinkId=472540

我這樣映射存儲過程,不知道是否丟失了某些東西。 字段和參數上的名稱相同:

...
modelBuilder.Entity<Facturas_prueba>()
                .MapToStoredProcedures(s =>
                s.Insert(i => i.HasName("nueva_factura") ));

...
modelBuilder.Entity<FacturasDetalle_prueba>()
                .MapToStoredProcedures(s =>
                s.Insert(i => i.HasName("nuevo_factura_detalle")));

這讓我發瘋,數據庫優先方法比這容易得多。 有什么建議么?

更新:我在答案中起作用的更改之前添加了一個存儲過程:

CREATE PROCEDURE nueva_factura(
    @folio varchar(10),
    @fecha datetime,
    @almacen varchar(10),
    @cliente varchar(10),
    @plaza varchar(10),
    @usuario varchar(10),
    @id_factura int = 0 OUTPUT
)
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    --SET NOCOUNT ON;

    -- Insert statements for procedure here
    INSERT INTO Facturas_prueba 
    VALUES(@folio, @fecha, @almacen, @cliente, @plaza, @usuario)

    SET @id_factura = SCOPE_IDENTITY()
END
GO

我剛剛發現,將SELECT SCOPE_IDENTITY()語句添加到存儲過程中的標識列中可以解決此問題:

ALTER PROCEDURE nueva_factura(
    -- Add the parameters for the stored procedure here
    @folio varchar(10),
    @fecha datetime,
    @almacen varchar(10),
    @cliente varchar(10),
    @plaza varchar(10),
    @usuario varchar(10),
    @id_factura int = 0 --OUTPUT
    )
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    --SET NOCOUNT ON;

    -- Insert statements for procedure here
    INSERT INTO Facturas_prueba VALUES(
        @folio,@fecha,@almacen,@cliente,@plaza,@usuario
    )

    SELECT SCOPE_IDENTITY() AS id_factura
END
GO

注釋中對為何需要插入內容的任何澄清都將不勝感激。

謝謝。 添加SELECT SCOPE_IDENTITY() AS MyId為我做到了。

至少對我來說,這是必要的原因是,當實體框架導入存儲過程時,它期望得到MyId的結果。

我最初return SCOPE_IDENTITY() ,這導致DbUpdateConcurrencyException ,並且錯誤Store update, insert, or delete statement affected an unexpected number of rows (0).

當我將存儲過程中的返回值更改為SELECT SCOPE_IDENTITY()我收到了錯誤消息,指出該列未正確映射。

使用完整的SELECT ... AS MyId可以正常工作。

這是我插入映射的修剪后的屏幕截圖: 映射的存儲過程的列綁定

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM