C# 实体框架冲突外键约束
我目前正在从事一个网站项目,该项目有一个存储库,作为一个单独的项目,使用实体框架用c编写,我以前从未使用过。我有一个问题,如果我试图添加一个新的船只通过前端运行时,我得到一个数据库错误 我花了一天的时间研究为什么这不起作用,最后决定我必须问这个问题。我已经看过很多关于这方面的问题,但是没有一个对我有帮助 我正在使用实体框架,由于外键约束,目前在向数据库添加“容器”时遇到问题 代码 VesselRepository.cs 这是发生错误的方法,特别是在SaveChanges行上,并显示以下消息:C# 实体框架冲突外键约束,c#,entity-framework,sql-server-2008,C#,Entity Framework,Sql Server 2008,我目前正在从事一个网站项目,该项目有一个存储库,作为一个单独的项目,使用实体框架用c编写,我以前从未使用过。我有一个问题,如果我试图添加一个新的船只通过前端运行时,我得到一个数据库错误 我花了一天的时间研究为什么这不起作用,最后决定我必须问这个问题。我已经看过很多关于这方面的问题,但是没有一个对我有帮助 我正在使用实体框架,由于外键约束,目前在向数据库添加“容器”时遇到问题 代码 VesselRepository.cs 这是发生错误的方法,特别是在SaveChanges行上,并显示以下消息: "
"The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Vessel_Attachment1". The conflict occurred in database "BoatRegistration", table "dbo.Attachment", column 'VesselId'.
The statement has been terminated."
以下是VesselConfiguration.cs和AttachmentConfiguration.cs文件:
我知道错误消息告诉我,当附件表中不存在外键时,我正在尝试将记录插入容器表,但是容器表中的vesselId具有标识规范,因此当我调试和检查vesselId时,它总是在插入之前设置为零
我尝试过的事情
尝试添加dbContext.Attachments.AddNewVesser.Attachment;在SaveChanges之前,我尝试添加haoptionalvsl=>vsl.Attachment.WithRequiredattment=>attment.Vesser;对于VesselConfiguration.cs,但这没有什么区别,我还尝试将vesselId设置为null,但由于vesselId不能为null,因此出现了一个错误
我还运行了SQL Profiler,使用从前端获取的一些测试数据,由于上述错误而失败的查询是:
exec sp_executesql N'INSERT [dbo].[Vessel]([PersonId], [VesselName], [ClassType],
[Makemodel], [Length], [Construction], [HullColour], [EngineTypeHP], [DataTagNumber],
[MMSINumber], [ArchiveStatus], [PermitNumber], [RegistrationNumber])
VALUES (@0, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, NULL, NULL)
SELECT [VesselId]
FROM [dbo].[Vessel]
WHERE @@ROWCOUNT > 0 AND [VesselId] = scope_identity()',N'
@0 int,@1 nvarchar(max) ,@2 nvarchar(max) ,@3 nvarchar(max) ,
@4 nvarchar(max) ,@5 nvarchar(max) ,@6 nvarchar(max) ,@7 nvarchar(max) ,
@8 nvarchar(max) ,@9 nvarchar(max) ,@10 bit',
@0=27,@1=N'dgfgdf',@2=N'dfgdf',@3=N'dgfgdf',@4=N'34534',@5=N'dfgdfg',
@6=N'dgfgf',@7=N'43534543',@8=N'5433',@9=N'33445',@10=0
当我在保存之前检查NewVesser对象时,一切看起来都井然有序,我输入的血管数据都存在,附件详细信息都在那里,即使PersonId与Person表中已经存在的记录匹配,唯一关闭的是VesselId,但我认为这将由SQL Server在插入时处理。就好像它没有对内存中的附件信息执行任何操作,但附件类是容器的一个属性:
您使用实体框架的方式与我使用它的方式完全不同。 我真的不知道是什么问题导致了你的方式,但你是对的一件事。实体框架应该在执行其SQL时为您创建一个ID 无论如何,如果没有其他办法,你可以试试这个
public int CreateVessel(Vessel newVessel)
{
using (BoatContext dbContext = new BoatContext())
{
newVessel.VesselId = new Vessel().VesselId;
//newVessel.Attachment = null
// OR
//Attachment attach = new Attachment();
//newVessel.Attachement = attach;
dbContext.Vessels.Add(newVessel);
dbContext.SaveChanges();
//return new vessel id
return Convert.ToInt32(newVessel.VesselId);
}
}
我认为这里的问题在于您的数据库模式 列VesselId配置为表“附件”中的主键,但它也应用作引用表Vessel的“VesselId”列的外键 另一方面,表“Vessel”中的列“VesselId”应重命名为“Id”,并仅用作主键,绝对不能用作外键 在您的情况下不可能添加新的容器实体,因为表“容器”中的外键约束会检查表“附件”中是否存在具有VesselId的条目,但事实并非如此
希望这能有所帮助。No这会产生相同的错误:INSERT语句与外键约束FK_Vesser_Attachment1冲突。数据库BoatRegistration表dbo.Attachment列“VesselId”中发生冲突。该语句已终止。请重试NewVesser.Attachment=null;错误的意思是newvasser.Attachment.vesselID中的vesselID与newvasser.vesselID不同。这就是为什么会出现这个错误。创建与NewVesser具有相同ID的附件或将其设置为空。如果dbschema要求您具有附件,则不能将其设置为null。
public class BoatContext : DbContext
{
public DbSet<Person> Persons { get; set; }
public DbSet<Vessel> Vessels { get; set; }
public DbSet<Club> Clubs { get; set; }
public DbSet<Attachment> Attachments { get; set; }
public BoatContext()
: base("Name=BoatRegistrationConnectionString")
{
System.Data.Entity.Database.SetInitializer<BoatContext>(null);
}
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new PersonConfiguration());
modelBuilder.Configurations.Add(new VesselConfiguration());
modelBuilder.Configurations.Add(new ClubConfiguration());
modelBuilder.Configurations.Add(new AttachmentConfiguration());
base.OnModelCreating(modelBuilder);
}
}
exec sp_executesql N'INSERT [dbo].[Vessel]([PersonId], [VesselName], [ClassType],
[Makemodel], [Length], [Construction], [HullColour], [EngineTypeHP], [DataTagNumber],
[MMSINumber], [ArchiveStatus], [PermitNumber], [RegistrationNumber])
VALUES (@0, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, NULL, NULL)
SELECT [VesselId]
FROM [dbo].[Vessel]
WHERE @@ROWCOUNT > 0 AND [VesselId] = scope_identity()',N'
@0 int,@1 nvarchar(max) ,@2 nvarchar(max) ,@3 nvarchar(max) ,
@4 nvarchar(max) ,@5 nvarchar(max) ,@6 nvarchar(max) ,@7 nvarchar(max) ,
@8 nvarchar(max) ,@9 nvarchar(max) ,@10 bit',
@0=27,@1=N'dgfgdf',@2=N'dfgdf',@3=N'dgfgdf',@4=N'34534',@5=N'dfgdfg',
@6=N'dgfgf',@7=N'43534543',@8=N'5433',@9=N'33445',@10=0
public class Vessel
{
public int VesselId { get; set; }
public int PersonId { get; set; }
public string VesselName { get; set; }
public string ClassType { get; set; }
public string Makemodel { get; set; }
public string Length { get; set; }
public string Construction { get; set; }
public string HullColour { get; set; }
public string EngineTypeHP { get; set; }
public string DataTagNumber { get; set; }
public string MMSINumber { get; set; }
public bool ArchiveStatus { get; set; }
public string PermitNumber { get; set; }
public string RegistrationNumber { get; set; }
public virtual Person Person { get; set; }
public virtual Attachment Attachment { get; set; }
}
public int CreateVessel(Vessel newVessel)
{
using (BoatContext dbContext = new BoatContext())
{
newVessel.VesselId = new Vessel().VesselId;
//newVessel.Attachment = null
// OR
//Attachment attach = new Attachment();
//newVessel.Attachement = attach;
dbContext.Vessels.Add(newVessel);
dbContext.SaveChanges();
//return new vessel id
return Convert.ToInt32(newVessel.VesselId);
}
}