我有一个通用的存储库类
public class Repository<T>
where T : class
{
AccountingEntities ctx = new AccountingEntities();
public T Add(T entity)
{
ctx.Set<T>().Add(entity);
SaveChanges();
return entity;
}
public T Update(T entity, int id)
{
T existing = ctx.Set<T>().Find(id);
if (existing != null)
{
ctx.Entry(existing).CurrentValues.SetValues(entity);
SaveChanges();
}
return existing;
}
public T GetSingle(Expression<Func<T, bool>> filter)
{
var query = ctx.Set<T>().AsNoTracking().Where(filter).FirstOrDefault();
return query;
}
private void SaveChanges()
{
ctx.SaveChanges();
}
}
我有两个表项和银行。每家银行都可以拥有多件商品。
我的表单中有两个按钮添加和编辑以及一个全局存储库。
当我打开表单并填写数据并单击添加时,记录将保存并且每个
事情还可以,但是当我点击编辑时会出现错误,请看
我的编辑按钮代码:
private void _btnEdit_Click(object sender, EventArgs e)
{
var item = repository.GetSingle(i => i.Id == id);
// here i update property of item
item = repository.Update(item, item.Id);
// here i get updated item
}
我的问题是在这行代码
var item = repository.GetSingle(i => i.Id == id);
当我获得项目时,它的导航属性(此处为银行实体)已填写
但是在这行代码
item = repository.Update(item, item.Id);
当我更新项目并获取它时,它的导航属性(银行)为空
我无法使用item。银行,因为它是空的。
最后,我了解了我创建全局存储库的问题在哪里
Repository<Item> repository = new Repository<Item>();
并在添加和编辑方法中使用存储库。当我创建
在每个添加和编辑方法中单独存储库它工作正常
我想知道为什么会这样?
答案 0 :(得分:1)
您需要使用Include()
使用预先加载,但请先修改GetSingle()
。 EF已默认启用延迟加载。所以你需要这样做:
public virtual T GetSingle(Func<T, bool> where,
params Expression<Func<T, object>>[] navigationProperties)
{
T item = null;
using (var context = new MainContext())
{
IQueryable<T> dbQuery = context.Set<T>();
//Apply eager loading
foreach (Expression<Func<T, object>> navigationProperty in navigationProperties)
dbQuery = dbQuery.Include<T, object>(navigationProperty);
item = dbQuery
.AsNoTracking() //Don't track any changes for the selected item
.FirstOrDefault(where); //Apply where clause
}
return item;
}
现在您可以加载Bank
实体
var item = repository.GetSingle(i => i.Id == id).Include(b=>b.Bank);
在这里找到more