我有一个小问题,实体框架4.1。
图像DTO的界面:
public interface IImage : IDtoBase
{
string FullFilePath { get; set; }
int Width { get; set; }
int Heigth { get; set; }
long ImageTypeId { get; set; }
IImageType Type { get; set; }
}
有配置上下文的代码:
// where TContext : DbContext, new()
private TInterface Invoke(Func<TContext, TInterface> callback)
{
using (var context = new TContext())
{
context.Configuration.AutoDetectChangesEnabled = true;
context.Configuration.LazyLoadingEnabled = true;
context.Configuration.ProxyCreationEnabled = true;
context.Configuration.ValidateOnSaveEnabled = true;
context.Database.Connection.Open();
return callback.Invoke(context);
}
}
有代码可以获得所需的DTO项目:
public TInterface Get(long id)
{
return Invoke(
context =>
{
TDto dto = context.Set<TDto>().FirstOrDefault(x => (x.Id == id));
return dto.Convert<TDto, TInterface>();
}
);
}
如果我设置context.Configuration.LazyLoadingEnabled = false
,那么图像DTO的“类型”属性为空(我想,没关系)。
如果context.Configuration.LazyLoadingEnabled
具有“true”值,则图像DTO的“Type”属性在“using”语句中具有正确的值,但在处理上下文后处理此属性 - “ObjectContext实例已被处置并且不能再用于需要连接的操作。“
即。图像DTO存在/未被处理,但其“类型”属性已被处理。
任何人都可以提供任何解决方案 - 不要处置“Type”属性(我想使用“using”语句而不是“Dispose”模式)?
答案 0 :(得分:4)
首先,您需要了解延迟加载的工作原理。 EF通过创建从您的实体类继承的代理来完成此操作,并覆盖导航属性访问行为。首次访问导航属性时,如果在代理类具有通过上下文加载它的逻辑之前未加载它。因此代理实例保留对上下文的引用。
当执行离开Invoke
方法时,将处理上下文。因此代理不能延迟加载导航属性。你可以做几件事来解决这个问题。
使用Include
方法急切加载
public TInterface Get(long id)
{
return Invoke(
context =>
{
TDto dto = context.Set<TDto>().Include(t => t.Type)
.FirstOrDefault(x => (x.Id == id));
return dto.Convert<TDto, TInterface>();
}
);
}
Invoke
方法内部处理上下文,则可以使用现有的上下文实例,该实例将在完成数据访问后进行处理。这可以通过IoC / DI框架完成。对于Web项目,生命周期通常仅限于一个请求。