I'm using code-first Entity Framework with a basic context that just consists of standard IDbSet collections where T is just a POCO class. On my context, I've disabled lazy loading. While there are "navigation properties" in my model classes, I've removed the virtual keyword from them.
The "Get All" methods in the repository do some custom filtering to ensure that the current user only sees the data that they own unless they are an administrator. I'm having a particular problem where I'm logged in as an administrator that also is associated with some records. Since the entity that I'm logged in as is loaded in the context, even though I have lazy loading disabled, virtual removed and am not using Include or Load, the objects in the results that have an association to my profile have the navigation property set automatically.
This is not code from my project, just an example to show the idea of what I'm doing. It probably has typos and syntax errors.
public class Record
{
public Guid Id { get; set; }
public string Name { get; set; }
public Owner Owner { get; set; } //No virtual keyword
public Guid OwnerId { get; set; }
}
public class Owner
{
public Guid Id { get; set; }
public string Name { get; set; }
public Collection<Record> Records { get; set; } //No virtual keyword
}
public class Context : DbContext
{
IDbSet<Owner> Owners { get; set; }
IDbSet<Record> Records { get; set; }
public static Context Create()
{
Context context = new Context();
context.Configuration.LazyLoadingEnabled = false; //Lazy loading disabled
return context;
}
}
public class Repository
{
private Context Context { get; set; }
public Owner CurrentOwner { get; private set; }
public Repository()
{
Context = Context.Create();
//Code here to get the application user and look up an associated "owner"
//entity if the user is an "owner" (they could just be an administrator)
//but the GetCurrentOwnerOrNull uses the Context to find the user
CurrentOwner = GetCurrentOwnerOrNull();
}
public IQueryable<Record> GetRecords(bool asAdmin)
{
IQueryable<Record> records = Context.Records; //Not including or loading Owner
if (asAdmin)
{
//Verify that the application user is an admin and throw exception otherwise
}
else
{
if (CurrentOwner == null)
{
//Throw a security exception
}
records = records.Where(r => r.OwnerId == CurrentOwner.Id);
}
return records;
}
}
So again, the problem with the above is that if I was to run that code as an Owner, whether administrator or not, then those Records that I Own will have the Owner property set instead of null. I want the entity framework to get out of my business and not automatically set this. It's causing problems downstream, especially when running the code as an administrator and an owner, so you get some records back with Owner = null and some with Owner set. It's annoying. Make it stop for me please.