有一个" DbUpdateException未被用户代码"处理。运行代码时出错

时间:2017-03-02 16:00:48

标签: c# .net asp.net-mvc visual-studio

当我运行我的DbInitializer时," context.SaveChanges"显示错误,它说"类型' Microsoft.EntityFrameworkCore.DbUpdateException'发生在Microsoft.EntityFrameworkCore.dll中,但未在用户代码"

中处理

我已经下载了几个不同的NuGet包,但仍然存在错误。有什么想法吗?

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using Microsoft.EntityFrameworkCore;
 using Microsoft.Extensions.DependencyInjection;
 using FinalTeamProject.Data;

namespace FinalTeamProject.Models
{
public static class DbInitializer
{
    public static void Initialize(BookingContext context)
    {
        context.Database.EnsureCreated();

        // Look for any students.
        if (context.Customers.Any())
        {
            return;   // DB has been seeded
        }

        var customers = new Customer[]
        {
        new Customer{ID=201,FirstName="Joe",LastName="Gatto",Telephone="07580043213"},
        new Customer{ID=202,FirstName="Sal",LastName="Vulcano",Telephone="0758243454"},
        new Customer{ID=203,FirstName="James",LastName="Murray",Telephone="07580043290"},
        new Customer{ID=204,FirstName="Brian",LastName="Quinn",Telephone="075800432800"},
        new Customer{ID=205,FirstName="Joe",LastName="Gato",Telephone="0758004313"},
        new Customer{ID=206,FirstName="Sal",LastName="Vulcno",Telephone="075823454"},
        new Customer{ID=207,FirstName="James",LastName="Muray",Telephone="0750043290"},
        new Customer{ID=208,FirstName="Brian",LastName="Quin",Telephone="07500432800"}

        };
        foreach (Customer s in customers)
        {
            context.Customers.Add(s);
        }
        context.SaveChanges();

内在例外:

{System.Data.SqlClient.SqlException: Cannot insert explicit value for identity column in table 'Customer' when IDENTITY_INSERT is set to OFF.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
at System.Data.SqlClient.SqlDataReader.get_MetaData()
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior)
at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection connection, String executeMethod, IReadOnlyDictionary`2 parameterValues, Boolean closeConnection)
at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteReader(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues)
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection connection)
ClientConnectionId:a4073037-3f12-4a01-9019-ab632c3325a0
Error Number:544,State:1,Class:16}

2 个答案:

答案 0 :(得分:2)

Customer.Id列在数据库中标记为Identity列。您无法显式设置此列的值。您正在设置Customer.ID属性的值。这就是你看到这个例外的原因。

在将记录插入表时,SQL Server将为IDENTITY列分配值。

所以你有以下解决方案。

One - 从数据库中的列中删除IDENTITY约束。这样您当前的代码就可以正常工作。

两个 - 您没有为Customer.ID属性

指定值
var customers = new Customer[]
{
    new Customer{FirstName="Joe",LastName="Gatto",Telephone="07580043213"},
    new Customer{FirstName="Sal",LastName="Vulcano",Telephone="0758243454"},
    new Customer{FirstName="James",LastName="Murray",Telephone="07580043290"}
};
foreach (Customer s in customers)
{
    context.Customers.Add(s);
}
context.SaveChanges();

三 - 您将值分配给Customer.ID属性,但是在插入具有显式ID的行之前需要在表上设置indentity_insert,然后在插入后设置为OFF。

var customers = new Customer[]
{
    new Customer{ID=201,FirstName="Joe",LastName="Gatto",Telephone="07580043213"},
    new Customer{ID=202,FirstName="Sal",LastName="Vulcano",Telephone="0758243454"},
    new Customer{ID=203,FirstName="James",LastName="Murray",Telephone="07580043290"}
};

context.Database.ExecuteSqlCommand("SET IDENTITY_INSERT Customer ON")

foreach (Customer s in customers)
{
    context.Customers.Add(s);
}

context.Database.ExecuteSqlCommand("SET IDENTITY_INSERT Customer OFF")

第1和第3种方法的问题是您需要跟踪客户的最新插入ID,以便在尝试插入下一个客户时不会出现主键违规错误。

对于IDENTITY列,最好将其留给SQL服务器为其生成值。

答案 1 :(得分:0)

您的内部异常中有解释

  

{System.Data.SqlClient.SqlException:无法在表格中插入标识列的显式值'客户'当IDENTITY_INSERT设置为OFF时。

在数据库中打开IDENTITY_INSERT或从正在插入的数据中删除ID(数据库将负责生成它)