views:

46

answers:

1

I have 4 different models that I'm pulling information from for a grid in a view. This code excerpt is apart of my controller for my Index action. Each Model has a repository, partRepository, parts_comboRepository, vendor_partRepository, and manufacturer_partRepository, and i use those repositories to grab data for my joins.

            var nss_part_combo = from o in parts_comboRepository.FindAll_Parts_Combos()
                             join parts in partRepository.FindAll_Parts()
                             on o.FK_Parts_ID_PARTS equals parts.ID_PARTS into joined_parts
                             from parts in joined_parts.DefaultIfEmpty()
                             join vendor_parts in vendor_partRepository.FindAllVendor_Parts()
                             on o.FK_Vendor_Parts_ID_VENDOR_PARTS equals vendor_parts.ID_VENDOR_PARTS into joined_vendor_parts
                             from vendor_parts in joined_vendor_parts.DefaultIfEmpty()
                             join manufacturer_parts in manufacturer_partRepository.FindAllManufacturer_Parts()
                             on o.FK_Manufacturer_Parts_ID_MANUFACTURER_PARTS equals manufacturer_parts.ID_MANUFACTURER_PARTS into joined_manufacturer_parts
                             from manufacturer_parts in joined_manufacturer_parts.DefaultIfEmpty()
                             select new NSS.ViewModel.Part_ComboViewModel
                             {
                                 ...
                             };
        return View(new GridModel(part_combo));

When I run it I get an error about having different contexts. I fixed the issue by declaring an entity at the top of my controller and using that instead of my repository objects to get all my IEnumerables for the joins. Is this a good way to go about it? I feel like I've deviated somehow from what i'm supposed to do and created a hack to fix my issue. What would be the best practice for approaching this problem?

A: 

I'm using this approach:

// I'm using top level class - UnitOfWork which is Abstract factory for my Data access layer 
// Unit of work is the only class which can get me instances of repositories
// It is also the holder for ObjectContext
public class UnitOfWork : IUnitOfWork, IDisposable
{
    private ObjectContext _context;

    public UnitOfWork(string connectionString)
    {
        if (String.IsNullOrEmpty(connectionString))
        {
            throw new ArgumentNullException("connectionString");
        }

        _context = new ObjectContext(connectionString);
    }

    private IRepository<Post> _postRepository;

    public IRepository<Post> PostRepository
    {
       get
       {
           if (_postRepository == null)
           {
              // Repositories are defined in the same assembly as UnitOfWork and have internal contructor. 
               _postRepository = new PostRepository(_context);
           }

           return _postRepository;
       }
    }

    // Other repositories

    // Dispose()

    // Unit of work saves changes made to entities from all repositories.
    public void Flush()
    {
       _context.SaveChanges();
    }
}

Based on the complexity of application UnitOfWork is consumed by Business layer as dependency injection or directly by controller as dependency injection. You have to create custom ControllerFactory and use IoC to inject it. UnitOfWork is defined in IoC to be instantiated with per HTTP request lifetime.

Ladislav Mrnka