Q:

How do I maintain referential transparency between related entities without relying on a common data context instance?

Thanks for looking.
Background
In my .NET applications I usually have a Business Logic Layer (BLL) containing my business methods and a Data Access Layer (DAL) which contains my Entitiy classes and any methods for dealing with atomic entities (i.e. CRUD methods for a single entity).  This is a pretty typical design pattern. 
Here is a pseudocode example of what I mean:
BLL
public static int CreateProduct(ProductModel product){
    return DAL.SomeClass.CreateProduct(new DAL.Product{
       Name = product.Name,
       Price = product.Price
    });
}

DAL
public int CreateProduct(Product p){
    var db = new MyDataContext();        
    db.Products.AddObject(p);
    db.SaveChanges();
    return p.Id;
}

No problems with this simple example.
Ideally, all the business of instantiating a data context and using that data context lives in the DAL.  But this becomes a problem if I attempt to deal with slightly more complex objects:
BLL
public static int CreateProduct(ProductModel product){
    return DAL.SomeClass.CreateProduct(new DAL.Product{
       Name = product.Name,
       Price = product.Price,
       ProductType = DAL.SomeClass.GetProductTypeById(product.ProductTypeId) //<--PROBLEM
    });
}

Now, instead of saving the entity, I get the following error:
An entity object cannot be referenced by multiple instances of IEntityChangeTracker
Ok, so the answer to dealing with that is to pass a common data context to both calls:
BLL
    public static int CreateProduct(ProductModel product){

using{var db = new DAL.MyDataContext()){

        return DAL.SomeClass.CreateProduct(new DAL.Product{
           Name = product.Name,
           Price = product.Price,
           ProductType = DAL.SomeClass.GetProductTypeById(product.ProductTypeId, db) //<--CONTEXT
        }, db); //<--CONTEXT
    }
}

Problem
This solves the immediate problem, but now my referential transparency is blown because I have to:

Instantiate the data context in the BLL
Pass the data context to the DAL from the BLL
Create overridden methods in the DAL that accept a data context as a parameter.

This may not be a problem for some but for me, since I write my code in a more functional style, it is a big problem.  It's all the same database after all, so why the heck can't I deal with unique entities regardless of their data context instance?
Other Notes
I realize that some may be tempted to simply say to create a common data context for all calls.  This won't fly as doing so is bad practice for a multitude of reasons and ultimately causes a connection pool overflow.  See this great answer for more details.
Any constructive input is appreciated.

A:

Personally, I track my unit of work and associate a data context to it via static methods. This works great if you aren't talking about operations with long lifetimes, such as my current project, an ASP.NET application, where every request is a (mostly) distinct unit and a request start and end coincide with the unit start/end. I store data context in the request CurrentContext, which, if you aren't familiar with it, is basically a dictionary managed by the system that allocates a request-specific storage accessible by static methods. The work's already done for me there, but you can find lots of examples of implementing your own unit of work pattern. One DbContext per web request... why?
Another equally workable answer for many is injection. Used for this purpose (injecting datacontext), it basically mimics the code you wrote at the end of your question, but shields you from the "non-functional" stuff you dislike.
Yes, you are only accessing one database, but if you look closely, you will see the database is not the constraint here. That is arising from the cache, which is designed to permit multiple, differing, concurrent copies of the data. If you don't wish to permit that, then you have a whole host of other solutions available.

