entity-framework-core - 给定重复的唯一索引时,DbContext.AddAsync 是否会引发异常?

标签 entity-framework-core

我编写了以下代码来将人员添加到数据库中,我怀疑在添加人员之前是否需要检查现有电子邮件(唯一键)。

如果我尝试添加与现有人员具有相同电子邮件地址的人员,AddAsync 是否会引发异常?

我已经包含了一个 MVCE,其中包括我的服务、存储库和 DbContext,但实际上这只是关于一次调用的行为以及它是否引发异常。如果是这样,那是什么异常(exception)?

namespace Project
{
    public sealed class PersonService
    {
        private readonly PersonRepository personRepository;

        public PersonService(PersonRepository personRepository)
        {
            this.personRepository = personRepository;
        }

        public async Task<Person> AddAsync(Person person)
        {
            var existingPerson = await this.personRepository.GetByEmailAsync(person.Email);

            if (existingPerson != null)
            {
                throw new DuplicateEmailException(person.Email, $"The Email {person.Email} is already taken.");
            }

            await this.personRepository.AddAsync(person);

            return person;
        }
    }

    public sealed class PersonRepository
    {
        private readonly ProjectDbContext dbContext;

        public PersonRepository(ProjectDbContext dbContext)
        {
            this.dbContext = dbContext;
        }

        public async Task<Person> GetByEmailAsync(string email)
        {
            return await this.dbContext.Person
                .FirstOrDefaultAsync(p => p.Email == email);
        }

        public async Task AddAsync(Person person)
        {
            if (person == null)
            {
                return;
            }

            await this.dbContext.AddAsync(person);
            await this.dbContext.SaveChangesAsync();
        }
    }

    public sealed class ProjectDbContext : DbContext
    {
        public ProjectDbContext(DbContextOptions options)
            : base(options)
        {
        }

        public DbSet<Person> Person { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<Person>()
                .Property(p => p.Email)
                .IsRequired();

            modelBuilder.Entity<Person>()
                .HasIndex(p => new { p.Email })
                .IsUnique();
        }
    }
}

最佳答案

I am questioning the need to check for an existing email (the unique key) before adding the person. Will AddAsync throw an exception for me if I try to add a Person with the same email as an existing Person?

dbContext.AddAsync(person) 不会抛出任何错误,但当 _dbContext.SaveChanges(); 被调用时,将抛出以下异常:

SqlException: Cannot insert duplicate key row in object 'dbo.Persons' with unique index 'IX_Perosns_Email'. The duplicate key value is ([email protected]). The statement has been terminated.

因此,您应该在 Controller 或模型级别而不是在 PersonService.AddAsync() 服务方法中验证/检查这一点,以便您可以向最终用户显示正确的验证错误消息。

关于entity-framework-core - 给定重复的唯一索引时,DbContext.AddAsync 是否会引发异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55696665/

相关文章:

c# - Entity Framework Core 生成具有不明确列名的 SQL

c# - EF核心: inserting large amounts of data

c# - 如何在 EF core 2.1 中使用 FreeText

c# - ECONNRESET 在 CreatedAtAction 之后,使用 _context.AddRange() - EF 2.0

sql - Entity Framework 核心相当于 SQL 的 "IN"

c# - XUnit 测试 DbContext 没有处理

docker - Docker 容器中的 EF Core 迁移

c# - Identity Server 4 混合流错误与客户端 key

c# - 在数据库中存储动态JSON数据并通过键值搜索

entity-framework-core - EF core cosmos 外键