Advice on approach to organizing my business logic & data access?
By reviewing this I have two general comments to your code:

Transaction

Is there any reason to use explicit transaction scope? When you call SaveChanges on the context it already uses transaction. It either uses ambient transaction or create a new one database transaction. So unless you are using multiple transactional resources (multiple database connections, MSMQ, etc.) or calling SaveChanges multiple times you don't need to create transaction explicitly. It is point of unit of work to save changes as one atomic unit. Also one side note: Default transaction used in SaveChanges uses default (or current) isolation level configured on database connection. Default for SQL Server is ReadCommitted. Default isolation level for TransactionScope is Serializable.

Testing

You mentioned that you want to make this abstraction to be able to replace context for testing. If you mean unit testing you can stop and go back to redesign your interfaces. You cannot unit test your business layer code if it uses IQueryable (Linq-to-entities) exposed by your data access layer. There is currently no provider which can simulate linq-to-entities behaviour for your unit tests. Once you use same in memory collection to mock IQueryable you will use linq-to-objects in your unit tests instead. That means you will test different code. 

The only correct way is either:


Not expose IQueryable from your DAL. Keep all linq-to-entities queries as internal implementation of your repositories (= you must materialize result in repositories by for example calling .ToList).
Use integration tests against real test database instead of using unit tests with mocked data access layer


I wrote several answers about this problematic on Stack Overflow:


Unit testing DbContext
Using the repository pattern to support multiple providers


Check also linked answers in those questions.