1

I have an object User which references an object State. The foreign key is a string of StateID and is optional. A user is not required to reference a State. I have the classes defined as follows

public class User
{
    public int UserID {get; set'}
    public string StateID {get; set;}
    //some other properties

    public virtual State State {get; set;}
}


public class State
{
    public string StateID {get; set;}
    //other properties

    public ICollection<User> Users {get; set;}
}

When I try to do a linq query to get some users and their states, the State object is always null. I do get the StateID of my User of course so I know that is set properly.

My query looks like this:

var users = userRepo.where(x => x.StateID != null);

Also tried adding .ToList() to get the lazy load to execute which does not work either.

I have tried adding [key] annotation to StateID in State with no luck.

i have also tried giving up on lazy loading and using include("State") in my query also with no luck.

Any clues as to what I am doing wrong?

UPDATE I have also tried to explicitly specify the mapping as follows:

modelBuilder.Entity<User>()
  .HasOptional(t => t.State)
  .WithMany(b => b.Users)
  .HasForeignKey(t => t.StateID);
6
  • Could you show your model configuration? Where did you set that there is relations between this two classes? And did you try to use Include(x=>x.State)? Commented Jan 23, 2014 at 14:38
  • Does the SQL logging show any access of the State table? Commented Jan 23, 2014 at 18:21
  • @Get Arnold No I am not seeing any joins to the State table in the SQL output. Thoughts? Commented Jan 23, 2014 at 19:55
  • Yes, apparently EF is not aware of the fact that StateID is a foreign key. Can you show your mapping configuration? Commented Jan 23, 2014 at 20:07
  • Well, with this mapping and Include and ToList() I'd certainly expect State to be loaded (and lazy loaded without Include). Are you absolutely sure that the keys match? (No leading or trailing spaces, case issues) Commented Jan 23, 2014 at 21:07

1 Answer 1

1

Make sure the navigation property is defined correctly in User class. like below:

   public class User
    {
        public int UserID {get; set;}          
        public string StateID {get; set;}

        //some other properties
        public State State {get; set;}
    }

Then you can create a query using Include like below:

var users = userRepo.Where(i => i.StateID != null).Include("State").ToList();

Update:

If you want to use Lazy loading to achieve this, add virtual keyworkd to all navigation properties.

public class User
{
    public int UserID {get; set;}
    public string StateID {get; set;}
    public virtual State State{get; set;}
}

public class State
{
    public string StateID {get; set;}
    public string StateName { get; set; }
    public virtual ICollection<User> Users { get; set; }
}

Also make sure you didn't disable Lazy loading in your DbContext class like below:

this.Configuration.LazyLoadingEnabled = false; // disable Lazy loading

follow above steps, the Lazy loading should works, below is an example:

In your action method:

   ViewBag.Result = userRepo.Users.Where(i => i.StateID != null);

In your view

    @foreach (User item in @ViewBag.Result)
    {
        <div>@item.State.SomePropertyName</div>
    }
Sign up to request clarification or add additional context in comments.

9 Comments

So are you saying it is not possible to lazy load using the virtual keyword on The navigation property?
Of course it's possible to use lazy loading. From the code you provided, I didn't see anything wrong. It just give you an example to by using Include keyword. I updated my answer, take a look.
I have specified virtual on both ends of the relationship and I am still getting the same results. I have successfully setup these types of relationships before. I am thinking the difference in this situation is the string foreign key
hi @stephen776, from I see, the problem is not about string type foreign key property. I tested both of them using lazy loading and Include, all work for me. Did you execute the query in your view or you just use breakpoint to look at the query result in your action method?
I thought about that. That's why I give you an example about execute the query in the view. The problem is not about string type foreign key or Lazy loading. The problem is you didn't actually execute the navigation property. Try var users = userRepo.Where(i => i.StateID != null).Include("State").ToList(), it will give you the result you expect, when you use breakpoints to check the result.
|

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.