实体框架始终包含的数据是在上下文中,即使我不问吧(Entity Framework always i

2019-08-03 11:31发布

我使用MVC.NET网页API,EF与DB第一,我也懒加载关闭我的背景。 EF将返回太多数据,即使有惰性加载关闭。

例如,我有一个角色的用户。 当我查询用户和包含的作用,因为用户已经被加载到上下文Role.Users属性会自动填充数据。

为什么我不能得到EF给我正是我的要求吗? 还是我失去了一些大吗?

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 - 我想EF从不数据加载到导航属性/集合除非我.INCLUDE()它直接。 当序列化到JSON我想这正是我要求明确。 看来,即使有延迟加载过,那些已经在上下文(即通常是“循环引用”)导航属性将被加载并返回。

Answer 1:

您所看到的行为被称为关系Fixup时 ,你无法禁用它。

如果您正在加载用户角色序列化并将其发送到某处我猜你不想跟踪他们在,所以被装载的背景下,实体的变化,也没有必要将它们附加到上下文和您可以使用:

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

或使用投影到专门的序列化,通过@STLRick所建议的对象。



Answer 2:

我不希望它加载除了我告诉它包括任何。

它看起来像你需要使用显式加载 。 基本上,你可以加载这样的具体实体:

context.Include("Roles")

据我所知应该不包括相关的实体。 延迟加载确实应该被禁用,您可以加载导航性能显式地Load



Answer 3:

您使用需要什么,你只能选择Select()

var users = _db.Users.Select(x => new
{
    UserID = x.UserID,
    Title = x.Title,
    Email = x.Email,
    RoleID = x.RoleID
}).AsEnumerable();


Answer 4:

你是正确的,对,你会回来的导航性能,因为它们是由这使得他们要加载的串行“感动”懒加载。 延迟加载应该是,如果你想要的属性回来为空关。 这就是说,它“似乎”,一旦实体被加载到上下文(通过其他查询,例如),他们将被串行处理。 因此,答案是告诉串行不返回导航性能。 我已经能够找到要做到这一点,最好的办法是使用的DTO(数据传输对象)。 这使您可以返回正是你想要,而不是实际的实体数据。

你的DTO可能是这个样子:

public partial class UserDto
{
    public UserDto(user User)
    {
        UserID = user.UserID;
        Title = user.Title;
        //... and so on
    }
    public int UserID { get; set; }
    public string Title { get; set; }
    public string Email { get; set; }
    public int RoleID { get; set; }

    //exclude the Role navigation property from your DTO
}

......然后,你可以这样做:

return db.Users.Include(u => u.Role).Select(user => new UserDto(user));


Answer 5:

首先:打开延迟加载上。

第二:如果要筛选下来,你什么检索并返回,然后做一个自定义的返回对象或东西。

from u in db.Users
join r in db.Roles
  on u.RoleID equals r.RoleID
select new { u.UserID, u.Title, u.Email, r.RoleName }

或类似的东西。 你将有一个最小的回报对象和你的对象图将是微小的。



文章来源: Entity Framework always includes data that is in context even if I don't ask for it