Валидиране на уникално име FluentValidation с помощта на база данни

Имам модел Категория, който има поле за име и всяко име на категория трябва да е уникално. Направих проверка и тя работи, когато се опитам да създам нова категория, но имам проблем, когато се опитвам да я редактирам. Засега само проверява дали името съществува и, разбира се, го прави, когато се опитам да редактирам същата категория.

Модел

[Validator(typeof(CategoryValidator))]
public class Category
{
    public int ID { get; set; }
    public string Name { get; set; }
    virtual public ICollection<Image> Images { get; set; }
}

public class CategoryValidator : AbstractValidator<Category>
{
    public CategoryValidator()
    {
        RuleFor(x => x.Name).NotEmpty().WithMessage("Category name is required.").Must(UniqueName).WithMessage("This category name already exists.");
    }

    private bool UniqueName(string name)
    {
        ProjecteDataContext _db = new ProjecteDataContext();
        var category = _db.Categories.Where(x => x.Name.ToLower() == name.ToLower()).SingleOrDefault();

        if (category == null) return true;
        return false;
    }
}

Както можете да видите, имам функция UniqueName(string name), но как мога да предам ID или целия модел в нея, за да мога да проверя дали е същият идентификатор като модела, който се опитвам да редактирам, след което преминава. Как мога да предам нещо като UniqueName(string name, int? id)? Открих FluentValidation едва днес и не мога да разбера.


person Stan    schedule 15.11.2012    source източник


Отговори (1)


Валидаторът на предикат (известен още като Must) има претоварване, което приема предикат с два параметъра (валидиран обект и стойността на имота). Във вашия случай предикатът ще има тип Func<Category, string, bool>. Така че просто добавете параметър Category към вашия метод за проверка на уникалното име:

private bool UniqueName(Category category, string name)
{
        ProjecteDataContext _db = new ProjecteDataContext();
        var dbCategory = _db.Categories
                            .Where(x => x.Name.ToLower() == name.ToLower())
                            .SingleOrDefault();

        if (dbCategory == null) 
            return true;

        return dbCategory.ID == category.ID;
}
person Sergey Berezovskiy    schedule 15.11.2012
comment
странична бележка: трябва да изхвърлите DbContext веднага щом приключите с него, така че използвайте (var _db = new ProjecteDataContext()) - person Hamid Sadeghian; 14.11.2016
comment
Възможно ли е да се инжектира DbContext? - person Ish Thomas; 26.03.2020
comment
Краткият отговор на @IshThomas е да, можете да инжектирате контекста в валидатора. Помислете за конкретно търсене на инжектиране във валидатори и трябва да намерите отговори, свързани с него. Документацията на FluentValidation също споменава как да направите това. - person julealgon; 16.04.2020