我已经尝试了几个小时,但我无法将我的种子数据用于我的实体框架数据库。
我一直收到以下错误:
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.Appointment_dbo.Employee_EmployeeID". The conflict occurred in database "BezoekersDBContext", table "dbo.Employee", column 'ID'.
堆栈跟踪的更大部分:
System.Data.Entity.Infrastructure.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.Entity.Core.UpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.SqlClient.SqlException: The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.Appointment_dbo.Employee_EmployeeID". The conflict occurred in database "BezoekersDBContext", table "dbo.Employee", column 'ID'.
另一个烦恼:
每次我在程序包管理器控制台中运行update-database
时,它都会不断添加种子数据的第一部分Employee
表数据。这就是为什么employee表现在有大约6个条目,但Employee Table的主键是7,8,9,10,11和12.这可能/可能是问题的一部分。我想删除数据库以重置这些密钥并使用update-database
重新添加它,但是当我尝试删除数据库时,我收到一条错误消息,说明数据库正在使用中。
我在这里结束了我的智慧。我将删除我的数据库图表,模型,Dbcontext,SQL服务器表数据和种子数据。我希望你们能帮助我。 如果您发现我的模型有任何错误,请告诉我!帮助一个同事程序员!
我已经阅读this SO question(这是一个已经可以回答的问题)并且用户说我的外键应该可以为空。我的所有人都无法自负,他们都是必需的。另一位用户说了一些关于制作我的导航属性virtual
的信息,但是我已经删除了这个以消除this weird error导致我的网络API无法从数据库中检索数据返回给调用者:
如果您有导航属性,则将它们设为非虚拟。映射仍然有效,但它会阻止创建无法序列化的动态代理实体。 没有延迟加载在WebApi中很好,因为您没有持久连接并且无论如何都运行了.ToList()。
图表(使用EF Power Tools创建):
模型
访问者
public class Visitor
{
[Key]
public int ID
{ get; set; }
[Required]
public string FirstName
{ get; set; }
[Required]
public string LastName
{ get; set; }
//[Key] I have to configure this later
[Required]
[EmailAddress]
public string Email
{ get; set; }
public string Company
{ get; set; }
public string Image
{ get; set; }
public string PhoneNumber
{ get; set; }
public ICollection<Appointment> Appointments
{ get; set; }
}
预约
public class Appointment
{
[Key]
public int ID
{ get; set; }
[Required]
public int EmployeeID
{ get; set; }
[Required]
public string Location
{ get; set; }
public string Comment
{ get; set; }
[Required]
public DateTime Date
{ get; set; }
public ICollection<Visitor> Visitors
{ get; set; }
public ICollection<Collector> Collectors
{ get; set; }
[ForeignKey("EmployeeID")]
public Employee Employee
{ get; set; }
}
集电极
public class Collector
{
[Key]
public int ID
{ get; set; }
[Required]
public int AppointmentID
{ get; set; }
[Required]
public int EmployeeID
{ get; set; }
[Required]
public int Preference
{ get; set; }
[ForeignKey("EmployeeID")]
public Employee Employee
{ get; set; }
[ForeignKey("AppointmentID")]
public Appointment Appointment
{ get; set; }
}
员工
public class Employee
{
[Key]
public int ID
{ get; set; }
//[Key] I have to configure this later
[Required]
public int SAP_ID
{ get; set; }
[Required]
public string FirstName
{ get; set; }
[Required]
public string LastName
{ get; set; }
[Required]
[EmailAddress]
public string Email
{ get; set; }
public string Image
{ get; set; }
[Required]
public string PhoneNumber
{ get; set; }
public ICollection<Appointment> Appointments
{ get; set; }
}
的DbContext
public class BezoekersDBContext : DbContext
{
public BezoekersDBContext() : base("BezoekersDBContext")
{
}
public DbSet<Appointment> Appointments
{ get; set; }
public DbSet<Employee> Employees
{ get; set; }
public DbSet<Collector> Collectors
{ get; set; }
public DbSet<Visitor> Visitors
{ get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<Collector>().HasRequired(d => d.Employee).WithMany().WillCascadeOnDelete(false);
}
WillCascadeOnDelete已启用,因为Collector
为Employee
但Employee
并非总是为Collector
。 (收藏家是指接待访客并将他带到预约地点的人。他也是一名雇员)。
没有启用此选项给了我关于Cascade循环和路径的错误,我发现很多SO答案告诉我使用此选项来解决该问题。
表格的SQL代码
访问者
CREATE TABLE [dbo].[Visitor] (
[ID] INT IDENTITY (1, 1) NOT NULL,
[FirstName] NVARCHAR (MAX) NOT NULL,
[LastName] NVARCHAR (MAX) NOT NULL,
[Email] NVARCHAR (128) NOT NULL,
[Company] NVARCHAR (MAX) NULL,
[Image] NVARCHAR (MAX) NULL,
[PhoneNumber] NVARCHAR (MAX) NULL,
CONSTRAINT [PK_dbo.Visitor] PRIMARY KEY CLUSTERED ([ID] ASC)
);
预约
CREATE TABLE [dbo].[Appointment] (
[ID] INT IDENTITY (1, 1) NOT NULL,
[EmployeeID] INT NOT NULL,
[Location] NVARCHAR (MAX) NOT NULL,
[Comment] NVARCHAR (MAX) NULL,
[Date] DATETIME NOT NULL,
CONSTRAINT [PK_dbo.Appointment] PRIMARY KEY CLUSTERED ([ID] ASC),
CONSTRAINT [FK_dbo.Appointment_dbo.Employee_EmployeeID] FOREIGN KEY ([EmployeeID]) REFERENCES [dbo].[Employee] ([ID]) ON DELETE CASCADE
);
集电极
CREATE TABLE [dbo].[Collector] (
[ID] INT IDENTITY (1, 1) NOT NULL,
[AppointmentID] INT NOT NULL,
[EmployeeID] INT NOT NULL,
[Preference] INT NOT NULL,
CONSTRAINT [PK_dbo.Collector] PRIMARY KEY CLUSTERED ([ID] ASC),
CONSTRAINT [FK_dbo.Collector_dbo.Employee_EmployeeID] FOREIGN KEY ([EmployeeID]) REFERENCES [dbo].[Employee] ([ID]),
CONSTRAINT [FK_dbo.Collector_dbo.Appointment_AppointmentID] FOREIGN KEY ([AppointmentID]) REFERENCES [dbo].[Appointment] ([ID]) ON DELETE CASCADE
);
GO
CREATE NONCLUSTERED INDEX [IX_AppointmentID]
ON [dbo].[Collector]([AppointmentID] ASC);
GO
CREATE NONCLUSTERED INDEX [IX_EmployeeID]
ON [dbo].[Collector]([EmployeeID] ASC);
员工
CREATE TABLE [dbo].[Employee] (
[ID] INT IDENTITY (1, 1) NOT NULL,
[SAP_ID] INT NOT NULL,
[FirstName] NVARCHAR (MAX) NOT NULL,
[LastName] NVARCHAR (MAX) NOT NULL,
[Email] NVARCHAR (MAX) NOT NULL,
[Image] NVARCHAR (MAX) NULL,
[PhoneNumber] NVARCHAR (MAX) NOT NULL,
CONSTRAINT [PK_dbo.Employee] PRIMARY KEY CLUSTERED ([ID] ASC)
);
种子数据
现在,我的Employee表中有行,其ID从7开始,因为我已经删除了数据库并使用了Update-Database
。我已经更改了即将发布的代码示例以匹配这些主键。
如果某人有比使用.Single(x => x.ID == NUMBERHERE);
更好的解决方案,因为如果我收到更多错误并增加自动增量,我可能需要更改它,请告诉我!我搜索了很多解决方案,但我找不到任何东西!
internal sealed class Configuration : DbMigrationsConfiguration<BezoekersRegistratie_BackEnd2.DAL.BezoekersDBContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(BezoekersDBContext context)
{
var employees = new List<Employee>
{
new Employee { FirstName="Jan", LastName="Scholten", Email="JanScholten2948@outlook.com", Image="http://lorempixel.com/400/400", PhoneNumber="0675876573", SAP_ID= 20149203, Appointments = new List<Appointment>()},
new Employee { FirstName="Bart", LastName="de Vries", Email="BartDeVries23@outlook.com", Image="http://lorempixel.com/400/400", PhoneNumber="0655544422", SAP_ID=20148394, Appointments = new List<Appointment>()},
new Employee { FirstName="Denke", LastName="Eekhoorn", Email="DenkeEekhoorn39@gmail.com", Image="http://lorempixel.com/400/400", PhoneNumber="0674738383", SAP_ID=2039388, Appointments = new List<Appointment>() }
};
employees.ForEach(e => context.Employees.AddOrUpdate(p => p.ID, e));
context.SaveChanges();
var appointments = new List<Appointment>
{
new Appointment { Employee = employees.FirstOrDefault(e => e.ID == 7),Location = "Apeldoorn", Comment="Rolstoeltoegang is nodig!", Date = new DateTime(2015, 11, 12, 13, 14, 0), Visitors = new List<Visitor>(), Collectors = new List<Collector>() },
new Appointment { Employee = employees.FirstOrDefault(e => e.ID == 8),Location = "Zwolle", Comment="Kan laat zijn.", Date = new DateTime(2016,2,11,14,12,0), Visitors = new List<Visitor>(), Collectors = new List<Collector>() },
new Appointment { Employee = employees.FirstOrDefault(e => e.ID == 9),Location="Amsterdam", Comment="Geen speciale opmerking", Date = new DateTime(2015,12,18,15,15,0), Visitors = new List<Visitor>(), Collectors = new List<Collector>() }
};
appointments.ForEach(a => context.Appointments.AddOrUpdate(p => p.ID, a));
context.SaveChanges();
employees[0].Appointments.Add(appointments[0]);
employees[1].Appointments.Add(appointments[1]);
employees[2].Appointments.Add(appointments[2]);
context.SaveChanges();
var visitors = new List<Visitor>
{
new Visitor { FirstName="Sander", LastName="ten Brinke", Email="sander.ten.brinke@xs4all.nl", Company="BelastingDienst", Image = "http://lorempixel.com/400/400", PhoneNumber="0620556193", Appointments = new List<Appointment>() },
new Visitor { FirstName="Reinold", LastName="Boeve", Email= "reinold.boeve@gmail.com", Company="Harvy", Image= "http://lorempixel.com/400/400", PhoneNumber="0657373660", Appointments= new List<Appointment>() },
new Visitor { FirstName="Eleina", LastName="Nieborg", Email="eleinanieborg@outlook.com", Company="Windesheim", Image="http://lorempixel.com/400/400", PhoneNumber="0641401035", Appointments = new List<Appointment>() },
new Visitor { FirstName="Roy", LastName="Stobbelaar", Email="roystobbelaar@hotmail.com", Company="BelastingDienst", Image="http://lorempixel.com/400/400", PhoneNumber="0637628563", Appointments = new List<Appointment>() },
new Visitor { FirstName="Michel", LastName="Vaassen", Email="maf.vaassen@belastingdienst.nl", Company="BelastingDienst", Image="http://lorempixel.com/400/400", PhoneNumber="0638572843", Appointments= new List<Appointment>() }
};
visitors.ForEach(v => context.Visitors.AddOrUpdate(s => s.Email, v));
context.SaveChanges();
visitors[0].Appointments.Add(appointments[0]);
visitors[1].Appointments.Add(appointments[0]);
visitors[3].Appointments.Add(appointments[0]);
visitors[3].Appointments.Add(appointments[1]);
visitors[2].Appointments.Add(appointments[1]);
visitors[0].Appointments.Add(appointments[2]);
visitors[1].Appointments.Add(appointments[2]);
visitors[4].Appointments.Add(appointments[2]);
context.SaveChanges();
var collectors = new List<Collector>
{
new Collector { Appointment = appointments.FirstOrDefault(x => x.ID == 1), Employee = employees.FirstOrDefault(x => x.ID == 7), Preference = 1}, //employeeID = signle).id
new Collector { Appointment = appointments.FirstOrDefault(x => x.ID == 1), Employee = employees.FirstOrDefault(x => x.ID == 8), Preference = 2},
new Collector { Appointment = appointments.FirstOrDefault(x => x.ID == 1), Employee = employees.FirstOrDefault(x => x.ID == 9), Preference = 3},
new Collector { Appointment = appointments.FirstOrDefault(x => x.ID == 2), Employee = employees.FirstOrDefault(x => x.ID == 8), Preference = 1},
new Collector { Appointment = appointments.FirstOrDefault(x => x.ID == 3), Employee = employees.FirstOrDefault(x => x.ID == 9), Preference = 1},
new Collector { Appointment = appointments.FirstOrDefault(x => x.ID == 3), Employee = employees.FirstOrDefault(x => x.ID == 7), Preference = 2},
};
collectors.ForEach(c => context.Collectors.AddOrUpdate(p => p.ID, c));
context.SaveChanges();
appointments[0].Collectors.Add(collectors[0]);
appointments[0].Collectors.Add(collectors[1]);
appointments[0].Collectors.Add(collectors[2]);
appointments[1].Collectors.Add(collectors[3]);
appointments[2].Collectors.Add(collectors[4]);
appointments[2].Collectors.Add(collectors[5]);
context.SaveChanges();
appointments[0].Visitors.Add(visitors[0]);
appointments[0].Visitors.Add(visitors[1]);
appointments[0].Visitors.Add(visitors[3]);
appointments[1].Visitors.Add(visitors[3]);
appointments[1].Visitors.Add(visitors[2]);
appointments[2].Visitors.Add(visitors[0]);
appointments[2].Visitors.Add(visitors[1]);
appointments[2].Visitors.Add(visitors[4]);
context.SaveChanges();
}
}
我很抱歉代码的数量,但导致这个问题的所有代码都在那里,所以我希望有人可以帮助我!
请告诉我我需要做些什么来永远摆脱这个问题。我将永远为你负债!
修改-虽然写入:
在我发布此答案之前,我正在浏览可能有答案的问题,我发现This SO post.
提到以下内容:
正在发生的事情是你的对象的主键都有默认的int值(0)。当您将它们添加到上下文中时,EF检测到这一点并抛出错误(两个相同类型的对象不能具有相同的密钥,在本例中为0.我假设数据库中的主键字段设置为IDENTITY列并且将插入时自动增加+1。这可能听起来很奇怪,但您需要为对象提供占位符ID,这些ID将在插入时替换为IDENTITY值。
我将种子代码的第一部分更改为以下内容:
protected override void Seed(BezoekersDBContext context)
{
var employees = new List<Employee>
{
new Employee { ID = 1,FirstName="Jan", LastName="Scholten", Email="JanScholten2948@outlook.com", Image="http://lorempixel.com/400/400", PhoneNumber="0675876573", SAP_ID= 20149203, Appointments = new List<Appointment>()},
new Employee { ID = 2,FirstName="Bart", LastName="de Vries", Email="BartDeVries23@outlook.com", Image="http://lorempixel.com/400/400", PhoneNumber="0655544422", SAP_ID=20148394, Appointments = new List<Appointment>()},
new Employee { ID = 3,FirstName="Denke", LastName="Eekhoorn", Email="DenkeEekhoorn39@gmail.com", Image="http://lorempixel.com/400/400", PhoneNumber="0674738383", SAP_ID=2039388, Appointments = new List<Appointment>() }
};
employees.ForEach(e => context.Employees.AddOrUpdate(p => p.SAP_ID, e));
context.SaveChanges();
var appointments = new List<Appointment>
{
new Appointment { Employee = employees.FirstOrDefault(e => e.ID == 7),Location = "Apeldoorn", Comment="Rolstoeltoegang is nodig!", Date = new DateTime(2015, 11, 12, 13, 14, 0), Visitors = new List<Visitor>(), Collectors = new List<Collector>() },
new Appointment { Employee = employees.FirstOrDefault(e => e.ID == 8),Location = "Zwolle", Comment="Kan laat zijn.", Date = new DateTime(2016,2,11,14,12,0), Visitors = new List<Visitor>(), Collectors = new List<Collector>() },
new Appointment { Employee = employees.FirstOrDefault(e => e.ID == 9),Location="Amsterdam", Comment="Geen speciale opmerking", Date = new DateTime(2015,12,18,15,15,0), Visitors = new List<Visitor>(), Collectors = new List<Collector>() }
};
//Other code here
这给了我以下错误:
序列包含多个元素
堆栈跟踪的更大部分:
System.InvalidOperationException: Sequence contains more than one element
at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__2[TResult](IEnumerable`1 sequence)
at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot)
at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[TResult](Expression expression)
at System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](Expression expression)
at System.Linq.Queryable.SingleOrDefault[TSource](IQueryable`1 source, Expression`1 predicate)
at System.Data.Entity.Migrations.DbSetMigrationsExtensions.AddOrUpdate[TEntity](DbSet`1 set, IEnumerable`1 identifyingProperties, InternalSet`1 internalSet, TEntity[] entities)
at System.Data.Entity.Migrations.DbSetMigrationsExtensions.AddOrUpdate[TEntity](IDbSet`1 set, Expression`1 identifierExpression, TEntity[] entities)
at BezoekersRegistratie_BackEnd2.Migrations.Configuration.<>c__DisplayClass1_0.<Seed>b__0(Employee e) in C:\BezoekersRegistratie\Stagiairs\Reinold Boeve\BezoekersRegistratie_BackEnd2\BezoekersRegistratie_BackEnd2\Migrations\Configuration.cs:line 26
at System.Collections.Generic.List`1.ForEach(Action`1 action)
at BezoekersRegistratie_BackEnd2.Migrations.Configuration.Seed(BezoekersDBContext context) in C:\BezoekersRegistratie\Stagiairs\Reinold Boeve\BezoekersRegistratie_BackEnd2\BezoekersRegistratie_BackEnd2\Migrations\Configuration.cs:line 26
我觉得我离我更近了。有人可以帮我解决这个问题吗?