简体   繁体   中英

How to access navigation properties in EF using repository pattern

Context: ASP.NET web application

The Base Repository (abstract class) implements the needed base functionality from which all other repositories inherit: ie -PersonRepo -AddressRepo

EDIT: Where do you place the code which queries several db tables and some of them are not directly related as navigation property in the respective repository?

Now, what is the best way to access the navigation properties? It is very cumbersome when using the repository pattern. If there is not a convenient solution for this, I will stick to my old DAL layer with everything inside and work with DbContext directly.

I just came up with a temporary solution for accessing navigation properties in my PersonRepository implementation:

public Person InsertNewPersonWithAddress(Person p, Address addr)
        {
            this.Insert(p); // insert person
            var ar = new AddressRepository(this.ctx);
            ar.Insert(addr);  // insert address
            this.Addresses(p).Add(addr);  // add address to person

            return p;
        }

        /* Navigation Properties */ 
        ICollection<Address> Addresses(Person p)
        {
            return ctx.Entry<Person>(p).Collection<Address>("Addresses").CurrentValue;
        }

Base Repository class implements the following interface

public interface IRepository<T> where T : class
    {
        IQueryable<T> All();
        IQueryable<T> FindBy(Expression<Func<T, bool>> predicate);
        T Insert(T entity);
        IEnumerable<T> InsertMultiple(IEnumerable<T> items);
        T Delete(T entity);
        IEnumerable<T> DeleteMultiple(IEnumerable<T> items);
        T Update(T entity);
        IEnumerable<T> UpdateMultiple(IEnumerable<T> items);
        void Save();
    }

DB-Design:

Person --> PersonAddress(junction table) <-- Address

Any intelligent solution for this problem?

You are thinking about this the wrong way. The navigation property is a property of the Entity, not a property of the Repository. You don't need to instantiate a Repository for the navigation property, it can be added directly to the Entity.

public Person InsertNewPersonWithAddress(Person p, Address addr)
{
    p.Address = addr;
    this.Insert(p); // insert person

    return p;
}

Now, if you are inserting a new Person but want it attached to an existing Address (rather than inserting a new copy of both), you can expose the AddressId FK as a property on the Person Entity, and pass in the FK value to do the link. In either case, it's not necessary for this Repository to need access to the other.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM