After switching a project from the EntityObject generator to DbContext, I ran into an issue using some navigation properties on new objects. I’ve spent a significant amount of time researching the problem, and I’m no closer to a desirable solution.
First, the generated class definitions:
public partial class Category
{
public Category()
{
this.Limits = new HashSet<Limit>();
}
public int CategoryId {get; set;}
public string Name {get; set;}
public virtual ICollection<Limit> Limits { internal get; set; }
}
public partial class Limit
{
public int CategoryId {get; set;}
public string Description {get; set;}
internal virtual Category Category { get; set; }
}
I am creating test data during an integration test using the following code:
using (GFCAMDataContext db = new GFCAMDataContext())
{
limit = new Limit()
{
CategoryId = testData.CategoryId,
Description = "SignerController.Update"
};
db.Limits.Add(limit);
db.SaveChanges();
}
Without any other changes, the Limit.Category property of my newly-created Limit object does not return anything. However, if I query the desired Category from the DbContext before SaveChanges is called the navigation property on my new Limit starts returning the associated Category. With ObjectContext, the Category property is updated without any intervention from me.
I would like to have the same behavior as ObjectContext, but I can’t seem to find a way to achieve this goal. I’ve seen a couple of proposed solutions:
-
Make the navigation properties public. This had the same behavior, and isn’t desirable as the public navigation properties can cause issues during serialization and aren’t needed outside of my business layer.
-
Make all properties public virtual and use DbSet.Create to ensure proxy creation. This resulted in the same behavior, and isn’t necessarily desirable as I have code dynamically creating instances (i.e. I don’t have access to a DbSet at the time I am creating an entity instance).
Does anyone have any suggestions for a solution to this problem?
One solution would be to explicitly load the nested entity:
The other option, when proxies are enabled, is indeed to call
DbSet.Create<T>(). If you don’t have access to theDbSetinstance at the time you create your entities, you might want to expose a public method in your repository interface that allows that. For example: