【问题标题】:Can't Insert to Database with Mapped Stored Procedure无法使用映射存储过程插入数据库
【发布时间】:2015-10-27 23:43:52
【问题描述】:

我正在使用 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

【问题讨论】:

    标签: asp.net entity-framework asp.net-mvc-5 entity-framework-6


    【解决方案1】:

    我刚刚发现向存储过程中的标识列添加 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
    

    cmet 中任何关于为什么插入需要这样做的澄清将不胜感激。

    【讨论】:

      【解决方案2】:

      谢谢。添加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 它可以工作。

      这是我的插入映射的修剪屏幕截图:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-03
        • 1970-01-01
        • 2021-07-30
        • 2015-01-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多