Выдает ли DbContext.AddAsync исключение с учетом дублированного уникального индекса? - PullRequest
0 голосов
/ 15 апреля 2019

Я написал следующий код для добавления человека в базу данных, и я сомневаюсь в необходимости проверки существующего электронного письма (уникальный ключ) перед добавлением человека.

Будет ли AddAsync выдавать исключение для меня, если я попытаюсь добавить человека с тем же адресом электронной почты, что и существующий человек?

Я включил MVCE, включая мои службы, репозиторий и DbContext,но на самом деле речь идет о поведении одного вызова и о том, вызывает ли он исключение.Если да, то что это за исключение?

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();
        }
    }
}

1 Ответ

1 голос
/ 16 апреля 2019

Я подвергаю сомнению необходимость проверки существующего электронного письма (уникальный ключ) перед добавлением человека. Будет ли AddAsync выдавать исключение для меня, если я попытаюсь добавить человека с тем же адресом электронной почты, что и существующий человек?

dbContext.AddAsync(person) не будет выдавать никаких ошибок, но при вызове _dbContext.SaveChanges(); будет выдано следующее исключение:

SqlException: Невозможно вставить строку повторяющегося ключа в объект 'dbo.Persons' с уникальным индексом 'IX_Perosns_Email'. Дубликат значения ключа (foo@gmail.com). Заявление было прекращено.

Таким образом, вы должны проверить / проверить это на уровне контроллера или модели, а не в PersonService.AddAsync() методе обслуживания, чтобы вы могли показать правильное сообщение об ошибке проверки конечному пользователю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...