0

I'm just starting out with .NET and have been trying to perform CRUD operations on a table. The table has a trigger on it which sets the primary key. Now, the read, update and delete operations work without a hitch. My problem is with the create operation.

This is the trigger

create or alter trigger dbo.CreateEmpID on dbo.Employee instead of insert
as
begin

declare @NextId varchar(20)
declare @EmpName varchar(50)
declare @cur cursor
set @cur = cursor for select EmpName from inserted
open @cur
fetch next from @cur into @EmpName
while @@FETCH_STATUS = 0
begin
    select @NextId = 'EMP' + convert(varchar(20), isNull(max(convert(int, substring(EmpID, 4, len(EmpID)-3))),0)+1) from Employee
    insert into Employee(EmpID, EmpName) values (@NextId, @EmpName)
    fetch next from @cur into @EmpName
end
close @cur
deallocate @cur

end

This is the part of the code that creates new employees

//POST: Create
    [HttpPost]
    public ActionResult Create(Employee Emp)
    {
        DB.Employees.Add(Emp);
        DB.SaveChanges();
        return RedirectToAction("Index");
    }

This is the error I keep getting

System.Data.Entity.Validation.DbEntityValidationException: 'Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.'

I'm also confused by one other thing. There is another trigger on the same table that works AFTER DELETE which copies the deleted employee to another table. So is it just the INSTEAD OF triggers that have the problem or is it the code that's problematic.

Any help is appreciated.

EDIT :

I changed table to use sequences as mentioned in the first answer and it still give me the error. Also this is the detailed error

System.Data.Entity.Validation.DbEntityValidationException
  HResult=0x80131920
  Message=Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
  Source=EntityFramework
  StackTrace:
   at System.Data.Entity.Internal.InternalContext.SaveChanges()
   at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
   at System.Data.Entity.DbContext.SaveChanges()
   at Test.Controllers.HomeController.Index() in E:\vs\projects\Test\Test\Controllers\HomeController.cs:line 18
   at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
   at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c.<BeginInvokeSynchronousActionMethod>b__9_0(IAsyncResult asyncResult, ActionInvocation innerInvokeState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass11_0.<InvokeActionMethodFilterAsynchronouslyRecursive>b__0()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass11_2.<InvokeActionMethodFilterAsynchronouslyRecursive>b__2()
5
  • You can follow the directions of the exception message and inspect EntityValidationErrors. We cannot. Please look at those details and add them to the question. Commented Sep 9, 2021 at 12:17
  • Side note, a TRIGGER with a WHILE is going to be far from performant. It'll be agonisingly slow for even a couple of thousand rows. Why are you not using a set based approach?
    – Thom A
    Commented Sep 9, 2021 at 12:19
  • 1
    Looking again at the trigger though, I'd strongly recommend just storing an integer generated by IDENTITY or a Sequence and then apply the EMP prefix either as a computed column or even only in the presentation layer. Don't confuse presentation concerns with the data you should be storing in the database. By mixing in the presentation prefix, you've already made your job far harder than it needed to be. Commented Sep 9, 2021 at 12:26
  • 1
    Your trigger code is flawed and may get PK violations with concurrent inserts.
    – Dan Guzman
    Commented Sep 9, 2021 at 12:27
  • Consider the prefix is static, I personally see no need to add it in the database layer. If it were derived from another column, then it might be up for consideration.
    – Thom A
    Commented Sep 9, 2021 at 12:55

1 Answer 1

0

A number of things could go wrong here, but it's not worth troubleshooting, as you should never generate keys by querying max(id)+1 from the target table. It doesn't scale and is prone to generating deadlocks.

If you want a key like EMP1234 you can generate it with a SEQUENCE and a DEFAULT, see eg and How to generate unique incremental employee code(pattern: E0001, E0002, E0003, ... ) in the INSERT stored procedure in SQL Server?

But normally you would just use a SEQUENCE or an IDENTITY COLUMN and move on.

5
  • I tried doing the sequence thing as mentioned in the post but I'm still getting the same error in Visual studio Commented Sep 10, 2021 at 3:54
  • I tried it without the sequence and just an int for the primary key set by identity. It works just fine but why wont this work? Commented Sep 10, 2021 at 4:34
  • @PrithviEmmanuelMachado - same error - but we don't know the details, because the error says "some errors occurred, look here for the details" and either you haven't looked there or if you have, you haven't updated the question to tell us the details. Commented Sep 10, 2021 at 6:24
  • I posted the detailed error. I cannot make out what its saying. Please see if you can find the problem Commented Sep 10, 2021 at 11:43
  • You need to "See 'EntityValidationErrors'" which is a collection under DbEntityValidationException. Commented Sep 10, 2021 at 13:44

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.