Forcing EF ApplicationUser To Load Navigation Prop

2019-06-23 17:16发布

问题:

I am using EF6/.Net 4.5.1 to retrieve data for a listview in a usercontrol on a webform. I have modified the ApplicationUser to include a Navigation Property [1:1] using a FK attribute which has been working great.

public class ApplicationUser : IdentityUser
{
    public ApplicationUser()
    {
        CreateDate = DateTime.Now;
        :\\ deleted stuff
    }

    public int TaxID { get; set; }
    public System.Guid ApplicationId { get; set; }
    :\\ deleted stuff

    [ForeignKey("TaxID")]
    public virtual Personnel Personnel { get; set; }
}

The model was migrated and tested for storing and retrieving.

Everything works fine with a full postback.

However I added a button on the webpage that opens and closes a div which holds a UserControl responsible for creating a new Member. The UserControl throws an event that is consumed by the container. The Container then closes the div containing the UC, reopens the div with the Listview, calls the Listview DataBind() which calls the GetAllUsers().

The code:

public IQueryable<ApplicationUser> GetAllUsers()
{
    var manager = HttpContext.Current.GetOwinContext()
                             .GetUserManager<ApplicationUserManager>();
    var users = manager.Users.OrderBy(c => c.TaxID);

    return users;
}

A problem arises after the UserControl returns control to the Container.

The first retrieve - always has an ApplicationUser which does NOT have the Navigation property loaded. This means certain fields are never populated in the listview.

Subsequent Retrieves (a refresh of the page or calling Edit of a row) however, seem to trigger navigation properties to be present.

  1. How can I force EF to Include the navigational property. The syntax manager.Users.Include() does not exist in this context.

  2. Only the entities listed as dynamicproxies of ApplicationUser seems to have the navigational property present. So I'm mystified why the initial retrieve is Never a dynamicproxy.

  3. The listview's Datapager requires an IQueryable to implement its paging. I do not call .ToList() as the Datapager knows when to This has been working great ... once there is a full page refresh. Why would a page refresh be required for the navigational properties to materialize?

Any help ... thanks in advance ...

回答1:

Add

using System.Data.Entity;

and then you can use Include:

var users = manager.Users.Include(x=> x.Personnel).OrderBy(c => c.TaxID);

If you want to include the navigation anywhere, in IdentityConfig.cs file override ApplicationUserManager.Users like this:

public class ApplicationUserManager : UserManager<ApplicationUser>
{
    public override IQueryable<ApplicationUser> Users
    {
        get
        {
            return base.Users.Include(x=>x.Personnel);//include what you want here
        }
    }
    //Rest of the original code
}