Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework always includes data that is in context even if I don't ask for it

I am using MVC.NET web api, EF with DB first, and I have lazy loading turned off on my context. EF is returning way too much data, even with LazyLoading turned off.

For example, I have Users with one Role. When I query for Users and Include Role, the Role.Users property is automatically filled with data since Users have been loaded into the context.

Why can't I get EF to give me JUST what I request? Or am I missing something big here?

public partial class User
{
    public int UserID { get; set; }
    public string Title { get; set; }
    public string Email { get; set; }
    public int RoleID { get; set; }

    ....

    public virtual Role Role { get; set; }
} 

public partial class Role
{
    public int RoleID { get; set; }
    public string RoleName { get; set; }

    ....

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




return db.Users.Include(u => u.Role);
// ^^ user.Role.Users is filled with 1000s of users

TL;DR - I want EF to never load data into navigation properties/collections unless I .Include() it directly. When serializing to JSON I want just what I ask for explicitly. It seems that even with lazy loading off, navigation properties that are already in the context (ie usually "circular references") will be loaded and returned.

like image 788
Chris Putnam Avatar asked Dec 03 '12 20:12

Chris Putnam


People also ask

What is data context in Entity Framework?

DbContext is an important class in Entity Framework API. It is a bridge between your domain or entity classes and the database. DbContext is the primary class that is responsible for interacting with the database.

How does DbContext work in Entity Framework?

As per Microsoft “A DbContext instance represents a session with the database and can be used to query and save instances of your entities. DbContext is a combination of the Unit Of Work and Repository patterns.” In simplified way we can say that DbContext is the bridge between Entity Framework and Database.

How do you get entities back from a query without getting tracked by the context?

The AsNoTracking() extension method returns a new query and returned entities do not track by the context. It means that EF does not perform any additional task to store the retrieve entities for tracking. We can also change the default behavior of tracking at context instance level.

Is DbContext part of Entity Framework?

The DbContext class is an integral part of Entity Framework. An instance of DbContext represents a session with the database which can be used to query and save instances of your entities to a database. DbContext is a combination of the Unit Of Work and Repository patterns.


2 Answers

The behaviour your are seeing is called Relationship Fixup and you cannot disable it.

If you are loading users with roles to serialize them and sent them to somewhere I guess that you don't want to track changes of entities in the context they have been loaded in. So, there is no need to attach them to the context and you can use:

return db.Users.Include(u => u.Role).AsNoTracking();

Or use a projection into an object specialized for serialization, as suggested by @STLRick.

like image 86
Slauma Avatar answered Oct 20 '22 11:10

Slauma


You can select only what you need by using Select().

var users = _db.Users.Select(x => new
{
    UserID = x.UserID,
    Title = x.Title,
    Email = x.Email,
    RoleID = x.RoleID
}).AsEnumerable();
like image 2
Stan Avatar answered Oct 20 '22 11:10

Stan