有没有一种方法可以获得EntityA
的列表而没有相关的导航,即使DbContext有它们也是如此。我需要这个用于序列化。
我尝试关闭Lazy loading
并明确.Include
任何相关实体。但是如果DbContext已经加载了它们,那么无论如何都会包含它。
Senario是这样的:
public class LookupRepository : ILookupRepository
{
private readonly CustomDbContext _dbContext;
public LookupRepository(CustomDbContext dbContext) {
if(dbContext == null)
throw new ArgumentNullException("dbContext");
_dbContext = dbContext;
}
public IEnumerable<Country> GetCountriesFull() {
return _dbContext.Set<Country>()
.Include(c => c.Areas)
.Include(c => c.Continent)
.ToList();
}
public IEnumerable<Country> GetCountries() {
return _dbContext.Set<Country>()
.ToList();
}
public IEnumerable<Continent> GetContinents() {
return _dbContext.Set<Continent>()
.ToList();
}
public IEnumerable<Area> GetAreas() {
return _dbContext.Set<Area>()
.ToList();
}
}
我注入的DbContext初始化如下:
public CustomDbContext CreateDbContext(){
var dbContext = new CustomDbContext();
dbContext.Configuration.ProxyCreationEnabled = false;
return dbContext;
}
所以这个使用干净的DbContext 的测试通过:
[Test]
public void GetCountries_CalledOnce_ReturnsCountriesWithoutNavigations() {
var sut = CreateLookupRepository();
var countries = sut.GetCountries();
CollectionAssert.IsNotEmpty(countries);
Assert.That(countries.Select(c => c.Continent), Is.All.Null);
Assert.That(countries.Select(c => c.Areas), Is.All.Null);
}
但是这个包含对GetCountriesFull
的所有号召的失败:
[Test]
public void GetCountries_AfterCallingGetCountriesFull_StillReturnsNoNavigations() {
var sut = CreateLookupRepository();
var fullCountries = sut.GetCountriesFull();
var countries = sut.GetCountries();
CollectionAssert.IsNotEmpty(countries);
Assert.That(countries.Select(c => c.Continent), Is.All.Null);
Assert.That(countries.Select(c => c.Areas), Is.All.Null);
}
关于如何做到这一点的任何建议?我想过使用工厂为每个方法创建一个新的dbContext (无论如何这个代码只在我的应用程序启动时运行,数据作为Singleton保留在内存中),但我认为必须有一个更好的解决方案
答案 0 :(得分:2)
最简单的方法是使用AsNoTracking()
获取实体。通过这样做,您告诉EF不要将实体添加到其内部缓存中,并且不会解析实体关系。
但是这里(再次)额外的存储库层对你不利,因为你不能只做一个像
这样的调用var fullCountries = sut.GetCountriesFull().AsNoTracking();
您必须进行重载,或添加bool withTracking
之类的参数,或者使用选项初始化存储库以始终(或从不)使用AsNoTracking()
。
答案 1 :(得分:1)
如果您不在乎不必要地加载它们(或者由于其他原因已经填写了它们),只需将所有导航属性设置为null
,如果您不希望它们通过了。
您还可以将[XmlIgnore]
属性添加到导航属性中,这样序列化程序就不会包含它们。这也可以防止同样的问题。
答案 2 :(得分:-1)
亲爱的,有很多方法可以做到这一点 1)如果您使用的是代码,请按照
进行操作protected override void OnModelCreating(DbModelBuilder modelBuilder) {
base.Configuration.LazyLoadingEnabled = false;
}
2)edmx文件在和定义中有一个延迟加载属性,你可以将延迟加载设置为false:
public MyEntitiesContext() : base("name=MyEntitiesContext", "MyEntitiesContext")
{
this.ContextOptions.LazyLoadingEnabled = false;
OnContextCreated();
}
或只是这样做
public BlogContext() : base()
{
this.Configuration.LazyLoadingEnabled = false;
}