1
\$\begingroup\$

I have an Entity Framework table of Addresses. I'm building a Repository that would allow me to search for an Address by either parts of the Address or the whole address.

Here's what I've got so far:

public class AddressRepository : Repository<Address>
{
    public List<Address> GetByAddress(string street, string city, string state, string zip)
    {
        return DbSet
            .Where(address => address.Street.Contains(street))
            .Where(address => address.City.Contains(city))
            .Where(address => address.State.Contains(state))
            .Where(address => address.Zip.Contains(zip))
            .ToList();
    }

    public List<Address> GetByStreet(string street)
    {
        return DbSet.Where(address => address.Street.Contains(street)).ToList();
    }

    public List<Address> GetByCity(string city)
    {
        return DbSet.Where(address => address.Street.Contains(city)).ToList();
    }

    public List<Address> GetByState(string state)
    {
        return DbSet.Where(address => address.Street.Contains(state)).ToList();
    }

    public List<Address> GetByZip(string zip)
    {
        return DbSet.Where(address => address.Street.Contains(zip)).ToList();
    }
}

Here is my Repository base class:

public class Repository<T> where T : class
{
    private readonly ApplicationDbContext _applicationDbContext = new ApplicationDbContext();

    protected DbSet<T> DbSet { get; }

    protected Repository()
    {
        DbSet = _applicationDbContext.Set<T>();
    }

    public virtual List<T> GetAll()
    {
        return DbSet.ToList();
    }

    public virtual T Get(int id)
    {
        return DbSet.Find(id);
    }

    public virtual void Add(T entity)
    {
        DbSet.Add(entity);
    }

    public virtual void SaveChanges()
    {
        _applicationDbContext.SaveChanges();
    }
}

Now, I'm thinking that in my GetByAddress function I should be calling my GetByStreet/City/State/Zip functions instead of repeating their code.

I haven't quite figured out how to do that, so any help or suggestions regarding that would be great.

As a side question: In my Repository class I have a GetAll function that returns the whole DbSet as a list, should I be calling GetAll().Where(...) instead of calling DbSet.Where(...)?

\$\endgroup\$
  • 2
    \$\begingroup\$ I suggest that you show your Repository base class as well. \$\endgroup\$ – 200_success Nov 21 '17 at 1:02
  • \$\begingroup\$ I've updated the post to include it now. \$\endgroup\$ – Ryan Taite Nov 21 '17 at 16:50
0
\$\begingroup\$

I would suggest that you don't use a repository at all. You already have a library that handles abstracting the database. You don't need the repository abstraction. And if you need some kind of abstraction, use a query object.

Some extensions are handy to build the query:

public static class AddressQueryExtensions
{
    public static IQueryable<Address> WhereStreetContains(this IQueryable<Address> query, string street)
    {
        return query.Where(address => address.Street.Contains(street));
    }

    public static IQueryable<Address> WhereCityContains(this IQueryable<Address> query, string city)
    {
        return query.Where(address => address.City.Contains(city));
    }

    public static IQueryable<Address> WhereStateContains(this IQueryable<Address> query, string state)
    {
        return query.Where(address => address.State.Contains(state));
    }

    public static IQueryable<Address> WhereZipContains(this IQueryable<Address> query, string zip)
    {
        return query.Where(address => address.Zip.Contains(zip));
    }
}

These can be combined however you want:

var addresses = DbSet
    .WhereStreetContains(street)
    .WhereCityContains(city)
    .WhereZipContains(zip)
    .Where(x => x.State == null)
    .ToList();

Some reading regarding repositories and ORMs.

https://lostechies.com/jimmybogard/2012/09/20/limiting-your-abstractions/ https://lostechies.com/jimmybogard/2012/10/08/favor-query-objects-over-repositories/ https://ayende.com/blog/3955/repository-is-the-new-singleton

\$\endgroup\$
  • \$\begingroup\$ Sorry for such a slow reply, it's been busy a time. The idea of leaving repositories in favor of Query objects is interesting and I'd have to dig into that some more. Thanks! \$\endgroup\$ – Ryan Taite Nov 22 '17 at 18:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.