2

Very strange issue, I've been using EF + Code First on a lot of projects but I can't figure out what's going on here.

I have the following entities :

public class Article { public int ID { get; set; } public string Title { get; set; } public virtual Media Image{ get; set; } public virtual Employee Author {get; set;} public MyEnum EnumValue {get; set;} public enum MyEnum {Value1, Value2} } public class Media { public int ID {get; set;} public double Length { get; set; } public string ContentType { get; set; } public byte[] Content { get; set; } } public class Employee { public int ID {get; set;} public string Name{get; set;} public string Email{get; set;} } 

With the following DbContext :

public class MyContext : DbContext { public MyContext() : base("ConnectionString") { this.Configuration.LazyLoadingEnabled = true; this.Configuration.ProxyCreationEnabled = true; } public DbSet<Article> Articles { get; set; } public DbSet<Employee> Employees { get; set; } public DbSet<Media> Medias { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<Article>().HasRequired(x => x.Image); modelBuilder.Entity<Article>().HasOptional(x => x.Author); } } 

Nothing special here, however whenever I retrieve an Article for example like that :

var article = _db.Articles.FirstOrDefault(x => x.ID == id); 

I have two problems Here is my problem :

  • The Image navigation property is empty. It is not null but all its properties have default values (0, null, etc...)
  • The Article object has a dynamic proxy but the navigation properties Image and Employees do not. If I remember correctly, navigations properties should be wrapped by dynamic proxies by default.
  • One important thing to note is that, the Employee navigation property has all its properties correctly loaded. This is good, however there is no dynamic proxy on it.

I've spent the last 2 hours trying to troubleshoot this and I'm running out of idea.

I would appreciate any hint / help,

Thanks !

Update : I've checked in the database and the foreign key is OK and the record in the Images table does exist.

1 Answer 1

3

Not sure I completely understand your question as you're playing a little fast and loose with terms here. Dynamic proxies, in the sense of Entity Framework, are classes that EF creates on the fly that inherit from actual entity classes and override virtual reference and navigation properties to enable lazy-loading. It's not something you really need to pay attention to, for the most part.

Navigation properties are always explicitly added. Entity Framework doesn't not add these for you under any circumstances. Technically what you have is two reference properties on your Article class, and that's it. As a result, Entity Framework creates a proxy of the Article class and returns an instance of that proxy from the results of your query. By attempting to access one of your reference properties, like Image, you activate the lazy-loading logic the proxy class added, causing a new query to be issued to the database to fetch that Media instance. The result will either be the object instantiated with the result of the database query or null. I can't say why you're getting an instantiated Media instance with "default" values. There's nothing regarding Entity Framework that would cause that. You must have some other code interfering with the instance.

As far as Media and Employee go, there's no navigation properties on these classes. If you would like to be able to access the set of related Articles, then you need to add something like:

public virtual ICollection<Article> Articles { get; set; } 
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks a lot for taking the time to reply to my question. Thank you, to me Article and Media are navigation properties with a 1 to 0 relashionship, and in your example Articles is a navigation property for a 1 to n relationship. Thank you for the explanation about proxies, but I am actually aware of that. I was pointing that no proxy is created around these navigation properties to help troubleshot the issue, because IIRC, it should normally be the case.
That was my point, though. No proxies are created because these particular classes do not have any reference or navigation properties on them. If there's nothing to lazy-load, then Entity Framework doesn't need to create a proxy.
Oh I see now, thanks! I'll continue to look in my code to see if there is an explanation for the Media property being null, but I really don't see what would cause that.
Just found, as you said, nothing to do with EF. I was assigning a new Media every time in the constructor of Article... However now I wonder when EF assigns the properties of a retrieved object with the values of the db. Perhaps it skips the properties that have been manually assigned in the constructor ? Thanks for you help, it's very refreshing to have the point of view of someone else.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.