c# - INSTEAD OF INSERT 设置的主键在实体框架中抛出错误(ASP.NET 框架 c#)
问题描述
我刚开始使用 .NET 并一直在尝试对表执行 CRUD 操作。该表上有一个触发器,用于设置主键。现在,读取、更新和删除操作可以顺利进行。我的问题是创建操作。
这是触发器
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
这是创建新员工的代码部分
//POST: Create
[HttpPost]
public ActionResult Create(Employee Emp)
{
DB.Employees.Add(Emp);
DB.SaveChanges();
return RedirectToAction("Index");
}
这是我不断收到的错误
System.Data.Entity.Validation.DbEntityValidationException: 'Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.'
我也对另一件事感到困惑。在同一个表上还有另一个触发器在删除后工作,它将删除的员工复制到另一个表。那么是只有 INSTEAD OF 触发器有问题,还是代码有问题。
任何帮助表示赞赏。
编辑 :
我将表格更改为使用第一个答案中提到的序列,但它仍然给我错误。这也是详细的错误
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()
解决方案
这里可能会出现很多问题,但不值得排除故障,因为您永远不应该通过max(id)+1
从目标表中查询来生成键。它无法扩展并且容易产生死锁。
如果您想要一个EMP1234
可以使用 SEQUENCE 和 DEFAULT 生成的密钥,请参阅例如和如何在 SQL Server 的 INSERT 存储过程中生成唯一的增量员工代码(模式:E0001、E0002、E0003、...)?
但通常您只需使用 SEQUENCE 或 IDENTITY COLUMN 并继续前进。
推荐阅读
- three.js - Three.js - 缩放背景图像以适应窗口,而不拉伸它
- sql-server - 如何使用 Asp.coreBoilerplate 实体框架实现级联删除?
- sapui5 - SAPUI5 SmartField 未处于编辑模式
- c# - 还原数据库时提取 Zip 文件
- django - Django中的临时数据存储工具
- c++ - 线程调用的函数对对象删除安全吗?
- mysql - MySQL 获取最新的记录而不使用连接中的自动增量字段
- java - 如何在rest api java中指定路径注释以接受任何路径?
- vba - 使用 VBA 从也包含 #N/A 值的单元格计算包含真/假输出的新单元格
- php - 使用 laravel 查询字符串