我有一个ASP MVC 3应用程序使用实体框架4从SQL Server数据库访问数据。EF4 - 分离对象的负载相关实体
我有一个场景,我使用EF4从数据库加载实体。然后,我可以按照正常情况加载相关实体。第一次加载后,我缓存实体。这要求将其序列化。在下一个请求中,我加载了相同的实体,但这次是从缓存中加载的。这会导致对象从上下文中分离出来,因为它不是从那里发起的。然后我无法正常加载相关的实体。
看起来很明显,原因是该对象与上下文分离,因此未被跟踪。我知道,当一个对象被上下文跟踪时,它会跟踪这些更改并在需要时通过执行实际的SQL语句来应用这些更改。但我不确定附加状态是否与加载相关实体的能力有关。
好的,这里有一些细节。这是模型结构。请注意,这是简化的,并不包括使EF4能够使用它的所有必要条件。这简单地展示了结构。
public class Segment
{
public Guid Id { get; set; }
public string Name { get; set; }
public SegmentGroup Group { get; set; }
}
public class SegmentGroup
{
public Guid Id { get; set; }
public string Name { get; set; }
public IEnumerable<Segment> Segments { get; set; }
}
然后我可以从数据库或缓存中获得一个段。这是在一个Manager类中完成的。再次非常简化。
public SegmentManager
{
public Segment GetSegment(Guid id)
{
string cacheKey = ... //generate specific cache key using Guid id
Segment segment = CacheProvider.Get<Segment>(cacheKey);
if(segment == null) //does not exist in cache yet - load from db and insert into cache
{
segment = repo.Find<Segment>(id); //roughly translates to:
//segment = dbcontext.Segments.SingleOrDefault(a => a.Id == id);
CacheProvider.Add(cacheKey, segment);
}
else //segment was found in cache - attach to context
{
repo.Attach<Segment>(segment); //dbcontext.Segments.Attach(segment);
}
return segment;
}
}
因此,这则有效地实现我用这个部门经理是这样的:
public ActionResult SegmentGroupName(Guid segmentId)
{
Segment segment = SegmentManager.GetSegment(segmentId); //Loaded from DB of Cache
return segment.Group.Name; //Group is accesable when segment is loaded from DB, but not from cache
}
所以问题是,我可以当段从数据库加载段访问的SegmentGroup,但不是从缓存中加载时。
所以我的问题是,我可以做什么从段缓存加载后,使我能够访问相关的实体的段。 我需要一个通用的解决方案,我可以将这个解决方案应用于我的所有模型管理者,因为所有的东西都是抽象的。 我试图避免急于加载所有相关的实体或手动加载它们之后的事实,因为这实际上比不高速缓存更昂贵。我只想让事情回到缓存之前的状态。 :)
请注意,代码演示非常简单,你需要做出一些现实的假设。