【发布时间】:2026-01-11 07:20:02
【问题描述】:
我已经阅读了很多关于使用 Context.Entry(entity).Collection(p=>p.Property).Load() 重新加载导航属性的 * 问题,但在我的情况下,它没有给我数据库中的更新值。
LazyLoading 和 ProxyCreation 选项设置为其默认值,我已阅读它们默认为 ON。
我有一个实体 Test 对象,我使用以下方法从数据库中获取了所有相关属性的预加载:
var test = Repository.GetById(testId, null, true, new Expression<Func<Test,object>>[] {
bt=>bt.Baselining,
ct=>ct.Baselining.BaselineTestCase,
dt=>dt.Baselining.BaselineTestCase.Baseline,
ft=>ft.Baselining.Transaction,
gt=>gt.Baselining.Transaction>Select(x=>x.Fields)
});
public virtual T GetById<T>(int id, Func<T,bool> where = null, bool trackChanges = false, params Expression<Func<T,object>>[] includeProps)
{
T item = null;
IQuerable<T> dbQuery = Context.Set<T>();
if(includeProps != null)
foreach(Expression<Func<T,object>> navProp in includeProps)
dbQuery = dbQuery.Include<T,object>(navProp);
if(where == null)
{
if(!trackChanges) item = dbQuery.AsNoTracking().FirstOrDefault(t=>t.Id == id);
else item = dbQuery.FirstOrDefault(t=>t.Id == id);
}
else
{
if(!trackChanges) item = dbQuery.AsNoTracking().Where(where).FirstOrDefault(t=>t.Id == id);
else item = dbQuery.Where(where).FirstOrDefault(t=>t.Id == id);
}
return item;
}
我正在尝试使用
重新加载 Baselining.Transaction.FieldsRepository.Reload(test);
Repository.Reload(test.Baselining.BaselineTestCase);
Repository.Reload(test.Baselining.BaselineTestCase.Baseline);
Repository.ReloadNavigationProperties(test.Baselining, x=>x.Transaction);
foreach(var tq in test.Baselining.Transaction)
Repository.ReloadNavigationProperties(tq, x=>x.Fields);
存储库方法类似于:
public virtual void ReloadNavigationProperties(TEntity,TElement>(TEntity entity, Expression<Func<TEntity,ICollection<TElement>>> navProp) where TEntity : class where TElement : class
{
Context.Entry(entity).Collection(navProp).Load();
}
public virtual T Reload<T>(T entity) where T : class {
Context.Entry(entity).Reload();
return entity;
}
我已经使用 SQL Profiler 调试了上述 ReloadNavigationProperties 执行,它确实会转到数据库并生成一个带有连接的 SQL 查询,但即使在重新加载后我的对象也没有更新。
在使用上述方法无法重新加载导航属性后,我采用了这种简单的方法,它有效...
foreach(var tq in test.Baselining.Transaction)
foreach(var tqfs in tq.Fields)
Repository.Reload(tqfs);
因为我为每个 TransactionQuery 大约有 100 个 TransactionQueryFields,并且这个嵌套的 foreach 需要 100 次重新加载每个字段,而且它非常非常慢而且应该很慢......
这里是实体
public class Test
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public int id {get;set;}
public virtual Baselining Baselining {get;set;}
public virtual ICollection<TestExecutionResult> TestCaseResults {get;set;} = new List<TestExecutionResult>();
}
public class Baselining
{
public Baselining() {}
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public int id {get;set;}
public DateTime BaseliningDate {get;set;}
public virtual BaselineTestCase BaselineTestCase {get;set;}
public virtual ICollection<TransactionQuery> Transaction {get;set;} = new List<TransactionQuery>();
}
public class BaselineTestCase
{
public BaselineTestCase() {}
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public int id {get;set;}
public virtual Baseline Baseline {get;set;}
public virtual ICollection<Baselining> Baselinings {get;set;} = new List<Baselining>();
public Baselining LastBaselining {
get {return Baselinings.OrderBy(x=>x.BaseliningDate).LastOrDefault(); }
}
}
public class TransactionQuery : TransactionItem
{
public TransactionQuery() {}
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public override int id {get;set;}
public virtual Baselining Baselining {get;set;}
public virtual ICollection<TransactionQueryField> Transaction {get;set;} = new List<TransactionQueryField>();
}
public class TransactionQueryField : TransactionItem
{
public TransactionQueryField() {}
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public override int id {get;set;}
public bool Compare {get;set;}
public bool Critical {get;set;}
}
public abstract class TransactionItem : BaseEntity<int> {
public string TestResultCode {get;set;}
}
public abstract class BaseEntity<T> {
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public virtual T Id {get;set;}
}
我想了解为什么使用导航属性预先加载不会加载更新的数据。因为根据我的理解,如果我渴望加载任何东西,它应该往返于数据库并获取更新的数据。但即使是通过重新加载进行急切加载,它也不会为我提供更新的值。
如果我没有正确解释,我很抱歉,但我将不胜感激有关如何更快地加载我的字段的任何帮助,可能是一次数据库往返。
【问题讨论】:
标签: c# linq entity-framework-6 dbcontext