繁体   English   中英

实体框架-导航属性是否不渴望/延迟加载?

[英]Entity Framework - Navigation Property Not Eager/Lazy Loaded?

我有以下实体:

public class Ticket 
{
    public int Id { get; set; }
    public string RequestBy { get; set; }
    public int PriorityId { get; set; }

    public ApplicationUser Requester { get; set; }
    public Priority Priority { get; set; }
}

public class ApplicationUser
{
    public ApplicationUser()
    {
        Id = Guid.NewGuid().ToString();
    }

    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class Priority
{
    public int Id { get; set; }
    public string Name { get; set; }
}

当我在控制器中按以下方式创建新故障单时:

 public class BaseController : Controller
{
    protected readonly IUnitOfWork UnitOfWork;

    public BaseController(IUnitOfWork unitOfWork)
    {
        UnitOfWork = unitOfWork; 
    }
}

public class TicketController : BaseController
{
    public TicketController(IUnitOfWork unitOfWork) : base(unitOfWork) { }

    [HttpPost]
    public ActionResult CreateTicket(CreateTicketVM viewModel)
    {
         // repopulate dropdowns incase we need to return view
         // viewModel.Priorities is IEnumerable list
         viewModel.Priorities = UnitOfWork.PriorityRepository.GetPriorities();

        //validation code removed for brevity...

        var ticket = new Ticket
        {
           RequestBy = !string.IsNullOrEmpty(viewModel.RequestBy) ? viewModel.RequestBy : User.Identity.GetUserId(),
           PriorityId = viewModel.PriorityId != 0 ? viewModel.PriorityId : (int)PriorityLevel.Medium,
        };

        UnitOfWork.TicketRepository.Add(ticket);
    }
}

现在,当我在调用.Add(ticket)后调试var ticket ,尽管设置了RequestBy值,为什么为什么要加载相关的导航属性Priority而不是Requester导航属性? 如您所见,我尚未针对任一导航属性定义任何virtual关键字?

扼杀这种情况仅适用于ApplicationUser类型的所有导航属性。 即使不使用virtual关键字,所有其他导航属性似乎也已加载???

我使用流利的api定义了RequestBy FK,如下所示:

modelBuilder.Entity<Ticket>()
 .HasRequired(x => x.Requester)
 .WithMany()
 .HasForeignKey(x => x.RequestBy);

以下是提供更多上下文的其他代码。

票库:

public class TicketRepository : ITicketRepository
{
    private readonly ApplicationDbContext _context;

    public TicketRepository(ApplicationDbContext context)
    {
        _context = context;
    }

    public void Add(Ticket ticket)
    {
        _context.Ticket.Add(ticket);
    }
}

优先级存储库:

public class PriorityRepository : IPriorityRepository
{
    private readonly ApplicationDbContext _context;

    public PriorityRepository(ApplicationDbContext context)
    {
        _context = context;
    }

    public IEnumerable<Priority> GetPriorities()
    {
        return _context.Priority.ToList();
    }
}

工作单位:

public class UnitOfWork : IUnitOfWork
{
    private readonly ApplicationDbContext _context;

    public ITicketRepository TicketRepository { get; private set; }
    public IPriorityRepository PriorityRepository { get; private set; }

    public UnitOfWork(ApplicationDbContext context)
    {
        _context = context;
        TicketRepository = new TicketRepository(_context);
        PriorityRepository = new PriorityRepository(_context);
    }

    public void Complete()
    {
        _context.SaveChanges();
    }
}

都不应该加载任何导航属性。 您看到的内容很可能是所谓的导航属性修复功能的结果-如果上下文已经跟踪了实体,即使您没有特别要求,EF也会更新引用该实体的实体的导航属性。

您可以使用var _context = new YourDbContext();轻松地进行验证var _context = new YourDbContext(); 局部变量而不是_context字段。 或类似这样的东西:

var ticket = new Ticket
{
    RequestBy = !string.IsNullOrEmpty(viewModel.RequestBy) ? viewModel.RequestBy : User.Identity.GetUserId(),
    PriorityId = viewModel.PriorityId != 0 ? viewModel.PriorityId : (int)PriorityLevel.Medium,
};

bool priorityLoaded = _context.Priority.Local.Any(e => e.Id == ticket.PriorityId);
bool userLoaded = _context.ApplicationUser.Local.Any(e => e.Id == ticket.RequestBy);

_context.Ticket.Add(ticket);

根据您的描述, priorityLoaded应该为trueuserLoaded - false

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM