[英]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.