c# - 使用实体框架的唯一主键
问题描述
我是 EF 的新手。假设我在 DB 中有一个这样的表:
ID FirstName LastName DateOfBirth
-------------------------------------------
1 John Smith 1.1.1990
2 Mary Wilson 5.1.1991
现在我使用 EF 将新实体插入到表中:
dbcontext.Persons.Add(new Person
{
FirstName = "John",
LastName = "Smith",
DateOfBith = "1.1.1990"
});
dbcontext.SaveChanges();
我需要代码来引发异常,因为该行已存在于数据库中,但 EF 所做的是将 ID 列增加 1 并创建新记录:
ID FirstName LastName DateOfBirth
--------------------------------------------
1 John Smith 1.1.1990
2 Mary Wilson 5.1.1991
3 John Smith 1.1.1990
EF甚至有能力做到这一点吗?
解决方案
您已经将您的ID
列定义为标识列,并且它已被视为您的主键,并且每次您在表中插入新记录时都会增加一。这就是允许您插入重复实体的原因。您需要指定需要将哪一列声明为 PK,如果您使用代码优先方法,则在您的模型中或使用Data Annotation,如下所示:
[Key]
public string FirstName { get; set; }
或者通过使用唯一约束:
[Index("IX_UniqueConstraint", 1, IsUnique = true)]
public string FirstName { get; set; }
[Index("IX_UniqueConstraint", 2, IsUnique = true)]
public string LastName { get; set; }
[Index("IX_UniqueConstraint", 3, IsUnique = true)]
public DateTime DateOfBirth { get; set; }
您还可以为此目的使用fluent API :
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Persons>().HasKey(c => new { c.FirstName, c.LastName, c.DateOfBirth });
}
或者,如果您使用的是 DB-first 方法,您可以在数据库中声明它。
推荐阅读
- c# - System.InvalidOperationException 未处理 HResult=-2146233079 消息=无法创建新服务:ChromeDriverService
- ruby-on-rails - Rails 应用程序中的时髦地图
- c++ - 如何解决与使用预处理器重新定义常用函数名称的标头的命名冲突?
- javascript - 将NodeJS readline保存到变量中?
- java - 将 Arraylist 转换为要通过 Whatsapp 共享的项目列表
- python - 在 Tensorflow 中实现 Keras 模型时的问题
- c++ - cout 不打印到终端屏幕 C++
- c# - 不同存储库类的事务范围
- python - 如何将每次迭代的结果附加到 CSV 文件中?
- android-studio - 从 Android 应用程序连接到 MariaDB