如何使用存储库模式加载子实体 [英] How to eager load child entities using repository pattern
问题描述
我有一个名为 Tour
的实体,可以有许多代理
。我可以添加代理,但是我不能删除它们。
I have an entity named Tour
which can have many Agents
. I am able to add agents, but I cannot remove them.
// _repo is injected....
var tour = _repo.GetById(tourId);
tour.AddAgent(new Agent(tour.TourId));
当我尝试调用 Tour.RemoveAgent()
方法没有什么是实际删除的。我在 Tour.RemoveAgent()
方法中设置一个断点我看到 _agents
属性的数量为 0
。
When I attempt to call the Tour.RemoveAgent()
method nothing is actually removed. I set a breakpoint inside the Tour.RemoveAgent()
method I see that the _agents
property has a count of 0
.
tour.RemoveAgent(agentId); // This doesn't work because _agents is empty
我必须为EF做一些特别的事情在我的存储库中检索 Tour
时,填充 _agents
属性
Do I have to do something special for EF to populate the _agents
property when I retrieve the Tour
from my repository?
我决定为每个聚合创建独特的存储库,这样很容易定义什么需要包含使用 Include()
函数。这是一个例子,我继承了 GenericRepository< T>
类(也包括在这个问题的底部)。
I decided to just create a Repository unique to each aggregate, that way it is easy to define exactly what needs to be included using the Include()
function. This is an example where I inherit from the GenericRepository<T>
class (which is also included at the bottom of this question).
public class TourRepository : GenericRepository<Tour>
{
public TourRepository(IDatabaseFactory databaseFactory) : base (databaseFactory)
{
}
public override Tour GetById(Guid id)
{
return dataContext.Tours
.Include(x => x.Agents)
.Single(x => x.TourId == id);
}
}
旅游课 p>
Tour Class
public partial class Tour
{
public Guid TourId { get; private set; }
protected virtual List<Agent> _agents { get; set; }
public Tour()
{
TourId = Guid.NewGuid();
_agents = new List<Agent>();
}
public void AddAgent(Agent agent)
{
_agents.Add(agent);
}
public void RemoveAgent(Guid agentId)
{
_agents.RemoveAll(a => a.AgentId == agentId);
}
}
代理类 p>
Agent Class
public partial class Agent
{
public Guid AgentId { get; private set; }
public Guid TourId { get; private set; }
public Tour Tour { get; private set; }
public Agent(Guid tourId)
{
TourId = tourId;
AgentId = Guid.NewGuid();
}
}
OnModelCreating
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// AGENTS ============================
modelBuilder.Entity<Agent>()
.HasKey(x => x.AgentId)
.Property(p => p.AgentId);
modelBuilder.Entity<Agent>()
.HasRequired(p => p.Tour)
.WithMany(t => t.Agents);
// TOURS =============================
modelBuilder.Entity<Tour>()
.HasKey(x => x.TourId)
.Property(x => x.TourId);
}
资源库类
public class GenericRepository<T> : IRepository<T> where T : class {
private MyContext dataContext;
private readonly IDbSet<T> dbset;
public GenericRepository(IDatabaseFactory databaseFactory)
{
DatabaseFactory = databaseFactory;
dbset = DataContext.Set<T>();
}
protected IDatabaseFactory DatabaseFactory
{
get;
private set;
}
protected MyContext DataContext
{
get { return dataContext ?? (dataContext = DatabaseFactory.Get()); }
}
// ... stuff removed for brevity ...
public T GetById(Guid id)
{
return dbset.Find(id);
}
}
推荐答案
尝试使受保护的虚拟List _agents {get;组; } public
Try making protected virtual List _agents { get; set; } public
public virtual List<Agent> _agents { get; set; }
您也可以通过执行以下操作来加载:
You can also eager load by doing something like this:
_databaseContext.Tours.Include(x => x.Agents).Single(x => x.TourId == tourId)
you can read more here: http://blogs.msdn.com/b/adonet/archive/2011/01/31/using-dbcontext-in-ef-feature-ctp5-part-6-loading-related-entities.aspx
这篇关于如何使用存储库模式加载子实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!