1

Imagine I have three classes like these :

public class Employee {
  public int EmployeeId {get;set;}
  public string Fname {get;set;}
  public File Picture {get;set;}
}

public class Employer {
  public int EmployerId {get;set;}
  public string Fname {get;set;}
  public string WorkingPlace{get;set;}
  public File Pictrue {get;set;}
}

public class File {
  public int FileId {get;set;}
  public byte[] Content {get;set;}
  public int Size {get;set;}
}

First, Is above code right way to save files and images of different entities? and then this is my context class:

public class MyDbContext : DbContext
{     
    public DbSet<File> Files { get; set; }
    public DbSet<Employee> Employees { get; set; }
    public DbSet<Employer> Employers { get; set; }
}

When I have query like this :

MyDbContext context = new MyDbContext
var q = from emp in context.Employees
        where emp.EmployeeId == 4
        select emp;
Console.WriteLine(q.First().Picture.FileId)

I get 0 as FileId while I see it's not 0 when I look in database. Somehow q.First().Picture is not set correctly

2
  • have you configured your modelBuilder? code first convention should map FileId on EmployeeId because of one-to-one relation. Anyways, Use Include(x=>x.Picture) before calling first to populate the navigation property before the value is materialized. Commented Aug 29, 2015 at 10:39
  • Imagine... What do your real classes look like, esp. the constructors? Commented Aug 29, 2015 at 22:47

1 Answer 1

2

You have two options available: eager loading or lazy loading. You can get more detail about them from this MSDN Article

Lazy loading is generally considered best practice, because you should only load what you need into memory by default; and then adjust accordingly on a per query basis.

For Lazy Loading, all you have to do is add virtual to the property in question:

public class Employee {
  public int EmployeeId {get;set;}
  public string Fname {get;set;}
  public virtual File Picture {get;set;}
}

This should make your query work as expected; however, it will probably result in 2 database calls, which would be inefficient. To address that, you can eager load the data as part of the query using .Include<>

MyDbContext context = new MyDbContext
var q = context.Employees.Include(e => e.Picture).Where(e => e.EmployeeId == 4);
var q2 = context.Employees.Include("Picture").Where(e => e.EmployeeId == 4); //Alternative syntax
Console.WriteLine(q.First().Picture.FileId)
Sign up to request clarification or add additional context in comments.

3 Comments

context.Employees doesn't have any Include function taking a lambda expression
@n3verLieMe updated my answer with the alternative syntax .Include("Picture") Not sure why that happens; probably a missing using.
The term you're looking for is Navigation Property.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.