【发布时间】:2017-05-28 16:39:50
【问题描述】:
根据其他问题(here 和 here),可以通过捕获抛出的异常并检查它的 InnerException 来捕获 Entity Framework 6 中的唯一键违规。
当使用重复的数据集调用DbContext.SaveChanges() 时,会引发异常,但这是一个相当标准的InvalidOperationException,它的InnerException 是null。
如何检测 Entity Framework Core 中的重复键违规?
更新更多上下文(双关语)
我试图捕捉/检测的具体违规行为是在通过多对多关系连接的两个实体(团队和用户)之间添加链接。
System.InvalidOperationException:无法跟踪实体类型“TeamUser”的实例,因为已在跟踪具有相同键的该类型的另一个实例。添加新实体时,对于大多数键类型,如果未设置键(即,如果键属性为其类型分配了默认值),则会创建一个唯一的临时键值。如果您为新实体显式设置键值,请确保它们不会与现有实体或为其他新实体生成的临时值发生冲突。附加现有实体时,请确保只有一个具有给定键值的实体实例附加到上下文。
用户实体类:
public class User
{
[Key]
public string Name { get; set; }
public ICollection<TeamUser> TeamUsers { get; set; }
}
团队实体类:
public class Team
{
[Key]
public string Id { get; set; }
[Required]
public string Name { get; set; }
public ICollection<Template> Templates { get; set; }
public ICollection<Checklist> Checklists { get; set; }
public ICollection<TeamUser> TeamUsers { get; set; }
}
TeamUser 实体类:
public class TeamUser
{
public string TeamId { get; set; }
public Team Team { get; set; }
public string UserName { get; set; }
public User User { get; set; }
}
我的DbContext 子类配置团队和用户之间的多对多关系:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var teamUserEntity = modelBuilder.Entity<TeamUser>();
teamUserEntity
.HasKey(tu => new { tu.TeamId, tu.UserName });
teamUserEntity
.HasOne(tu => tu.Team)
.WithMany(t => t.TeamUsers)
.HasForeignKey(tu => tu.TeamId);
teamUserEntity
.HasOne(tu => tu.User)
.WithMany(u => u.TeamUsers)
.HasForeignKey(tu => tu.UserName);
}
EF Core 已生成TeamUser 表,如下所示:
CREATE TABLE "TeamUser" (
"TeamId" TEXT NOT NULL,
"UserName" TEXT NOT NULL,
CONSTRAINT "PK_TeamUser" PRIMARY KEY ("TeamId", "UserName"),
CONSTRAINT "FK_TeamUser_Teams_TeamId" FOREIGN KEY ("TeamId") REFERENCES "Teams" ("Id") ON DELETE CASCADE,
CONSTRAINT "FK_TeamUser_Users_UserName" FOREIGN KEY ("UserName") REFERENCES "Users" ("Name") ON DELETE CASCADE
);
CREATE INDEX "IX_TeamUser_UserName" ON "TeamUser" ("UserName");
【问题讨论】:
-
您是否在数据库上下文中设置了唯一约束?
-
我的意思是这样的:entity.HasAlternateKey(p => new { p.ProductName }).HasName("U_ProductName");
-
@H.Herzl 请检查更新的问题,我已经添加了相关的实体类和
OnModelCreating方法。 -
对不起,我没有很好地解释,因为我理解你的问题,你需要捕捉一个独特的约束违规;所以我的建议是在 DbContext 中为您的唯一约束添加配置并尝试操作以查看异常详细信息,这有意义吗?
-
@H.Herzl 据我所知,我已经正确设置了唯一约束。我添加了相关的表模式,它显示主键是
TeamId和UserName的复合键。问题不在于防止重复,而是检测系统何时尝试插入重复。
标签: c# entity-framework .net-core entity-framework-core