I'm working with a tenant-segregated application and Entity Framework 6 in it. I identify the tenant by looking at the request host name, use that identification throughout the application, enter it in records that belong to the tenant, and so on.
At the conclusion of the request, all contexts are deleted. However, due to the high frequency of tenant lookups, I actually only perform each one once per host name before storing the objects in a read-only dictionary in memory.
The issue is that if nothing is done, there will be as many duplicate tenant records as there are requests (till the thing starts throwing because of now-ambiguous queries, anyway).
By including a call to DbSet, I was able to fix issue at first. My data store's constructor uses the function Attach() to attach the current tenant. The same object cannot be associated to numerous contexts, according to an exception that you receive if you make many queries at once: "An entity object cannot be referenced by multiple instances of IEntityChangeTracker." I doubt it would work well in a production setting because I occasionally cause this on my development machine by viewing pages too quickly.
I made an attempt to make changes by inputting the following call before saving:
Context.ChangeTracker.Entries<Tenant>().Single().State = EntityState.Unchanged;
Well, that also doesn't work. When I try to define the relationship between two objects because they are connected to distinct ObjectContext objects, I receive the following error.
Okay, how do I go about doing this? I simply want different rows with a foreign key reference to an existing tenant row PK (in terms of the final SQL result).
The Detach method has been recommended in several materials I've read that reference EF4, but I'm not sure I should be calling it now that it's hidden from the DbSet's public interface. If I am, I have no idea where. when I initially get the record?
Going to the context and retrieving the tenant record using the ID of the cached record is one way that does appear to work. Now though, I'm going and searching the database without any actual justification.
Would caching a non-change-tracking, non-entity perspective on the data make more sense? The tenant record appears to be a "pointer" to relationships using foreign keys.
To me, this makes sense:
Generally speaking, it appears that all you would need to do is persist the tenant id that is associated with one or more host names. Take the traditional ADO route here and remove the entity from your cache, only caching the POCO data you require.