Naomi
Naomi

Reputation: 718

Entity Framework / Base Repository class - Add check for duplicates

We have a few repository classes in our application with the methods like the following:

public override void Add(Template template)
    {
        CheckDuplicateDescription(template);
        base.Add(template);
    }

    public override void Update(Template template)
    {
        CheckDuplicateDescription(template);
        base.Update(template);
    }

    private void CheckDuplicateDescription(Template template)
    {
        if( _dbSet.Any(x => x.Descrip.Equals(template.Descrip.Trim()) && x.TemplateId != template.TemplateId))
        {
            throw new DuplicatePropertyException("Description", 
                string.Format(Messages.alreadyExistsWithValue, template.Descrip.Trim()));
        }
    }

I'm trying to figure out if there is a way to make this method to be generic and implement in the base repository class (so we can probably provide a bool property to tell we need to validate, perhaps also the name of the column to check and the name of Pk column). I am not sure how to write such a code in a generic way assuming Entity entity in the update method.

Upvotes: 0

Views: 403

Answers (1)

FractalCode
FractalCode

Reputation: 380

Well I have done things like this before. I hope i can help. What you can do is build an expression for the condition in the _dbSet.Any

Something like this:

 public Expression<Func<T,bool>> GetCondition(string nameProperty, string text)
        {
            var i = Expression.Parameter(typeof(T), "i");
            var prop = Expression.Property(i, nameProperty);
            var value = Expression.Constant(text);

            MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
            var containsMethodExp = Expression.Call(prop, method, value);
            var lambda = Expression.Lambda<Func<T, bool>>(containsMethodExp, i);

            return lambda;
        }

then you can use it like this:

private void CheckDuplicateDescription(T template)
        {
            var propDescription = GetPropertyNameDescription();//asuming you have the name of the Description property
            var value = GetValueDescription(template, propDescription);
            var condition = GetCondition(propDescription, value);

            if (_dbSet.Any(condition))
            {
                throw new DuplicatePropertyException("Description",
                    string.Format(Messages.alreadyExistsWithValue, template.Descrip.Trim()));
            }
        }

Upvotes: 2

Related Questions