0

I have an application working fine without triggers on tables.

Adding a trigger in order to track changes causes Entity Framework to return an error

Subquery returned more than 1 value" message.

However:

  1. Executing the insert by hand (SQL)
  2. Executing the sp_executesql generated by Entity Framework (retrieve with profile tool)

Both work fine. i.e.: not duplicate records.

I can't figure what is that situation. Here's the code:

T-SQL trigger:

CREATE TRIGGER [dbo].[trace_kIAlmacenTipo]
ON [dbo].[kIAlmacenTipo]
AFTER INSERT, UPDATE 
AS 
BEGIN 
    SET NOCOUNT ON;

    DECLARE @net_ip varchar(48), @login_name varchar(50), @net_address varchar(50)
    SET @net_ip = dbo.getIP()
    SET @login_name = dbo.getLogin()
    SET @net_address = dbo.getAddress()

    INSERT INTO [trk].[kIAlmacenTipo_trk]       
        (idAlmacenTipo, tipo, descripcion, baja, fkSesion, loginname, netip, netaddress, date)
       SELECT 
           i.idAlmacenTipo, i.tipo, i.descripcion, i.baja, i.fkSesion,
           @login_name, @net_ip, @net_address, GETDATE()
       FROM inserted i
END

SQL Server statement generated by EF (retrieved from profiling tool, work as expected from SQL Server Management Studio:)

exec sp_executesql N'UPDATE [dbo].[kIAlmacenTipo] SET [tipo] = @0, [descripcion] = @1, [baja] = @2, [fkSesion] = @3 WHERE ([idAlmacenTipo] = @4) ',N'@0 int,@1 nvarchar(50),@2 bit,@3 int,@4int',@0=6,@1=N'test++',@2=0,@3=4,@4=8

Controller code (work as expected without trigger on kIAlmacenTipo table)

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "idAlmacenTipo,tipo,descripcion,baja,fkSesion")] kIAlmacenTipo kIAlmacenTipo)
{
        if (ModelState.IsValid)
        {                     
            try
            {                    
                kIAlmacenTipo.fkSesion = Convert.ToInt32(Session["idSesion"]);

                db.Entry(kIAlmacenTipo).State = EntityState.Modified;
                db.SaveChanges(); // here ==> catching InnerException "SubQuery returned more than 1 value...."                                

                return RedirectToAction("Index");
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("", "Error: " + ex.Message);
            }
            return View(kIAlmacenTipo);
        }

        ViewBag.fkSesion = new SelectList(db.iOSesion, "idSesion", "ip", kIAlmacenTipo.fkSesion);
        return View(kIAlmacenTipo);
}

Thanks in advance.

Good day.

4
  • What is the output from SQL when you run 1 and 2 manually? Commented Sep 17, 2015 at 1:06
  • @BrentMannering By hand >> SQL outpout >> (1 row(s) affected), [dbo].[kIAlmacenTipo] "first table" apropriate record update, [trk].[kIAlmacenTipo_trk] the "trace one" 1 new record append.... Commented Sep 17, 2015 at 1:52
  • Could it be thrown by one of your functions? Try replacing dbo.getIP(), dbo.getLogin() and dbo.getAddress() with strings and test again. EF might be connecting with a different account so dbo.getLogin() might have a different result than your manual test. Commented Sep 17, 2015 at 4:05
  • @Padhraic that's right, dbo.getIP() function is responsible of this..... Thank you very much. Commented Sep 17, 2015 at 14:35

1 Answer 1

1

Could it be thrown by one of your functions? Try replacing dbo.getIP(), dbo.getLogin() and dbo.getAddress() with strings and test again. EF might be connecting with a different account so dbo.getLogin() might have a different result than your manual test.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.