一般的な問題と思われる問題が発生しました。データベースの値を更新していますが、EFはオブジェクトの元のメモリ内コピーを使用しており、これらの変更された値は表示されたデータに反映されません。これがなぜなのかは理解できますが、それを回避する方法がわかりません。
最も一般的な解決策は、MergeOptions.NoTracking
変更の追跡を完全にオフにし(またはAsNoTracking()
クエリ時に拡張メソッドを使用し)、オブジェクトにアクセスするたびに強制的に更新するように設定することです。これは私の目的には問題ありません。
他のリポジトリから継承する汎用ベースリポジトリがあります。
public abstract class RepositoryBase<T> where T : class
{
private readonly IDbSet<T> _dbset;
private readonly IUnitOfWork _unitOfWork;
protected RepositoryBase(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
_dbset = _unitOfWork.Database.Set<T>();
}
public virtual IQueryable<T> All()
{
return _dbset;
}
// Some other IQueryable methods here (Query, GetByProductCode etc)
public virtual T Get(long id)
{
return _dbset.Find(id);
}
}
そしてDbContext
このように:
public class Db : DbContext
{
private IDbSet<Product> _products;
public IDbSet<Product> Products
{
get { return _products ?? (_products = DbSet<Product>()); }
}
public virtual IDbSet<T> DbSet<T>() where T : class
{
return Set<T>();
}
public virtual void Commit()
{
base.SaveChanges();
}
}
All()
したがって、リポジトリのメソッドを変更すると、次のようになります。
public virtual IQueryable<T> All()
{
return _dbset.AsNoTracking();
}
希望する結果が得られました。製品を表示しているページが更新されると、データベースの更新が反映されます。Get()
ただし、この拡張メソッドはでのみ機能するため、メソッドでこれを行うことはできませんIQueryable
。
変更の追跡は必要ないので、理想的にはこれをレベルでオフにしたいのDbContext
ですが、これを行うための明確な方法はないようであり、主題に関するドキュメントはほとんどありません(誰かが指摘できない限り)私を誰かに?お願いします!)
DbContext
これらの構成オプションを無効にして、コンストラクターをに追加してみました。
public Db()
{
base.Configuration.ProxyCreationEnabled = false;
base.Configuration.AutoDetectChangesEnabled = false;
}
しかし、私は彼らが実際に何をしているのかを推測しているだけであり(私はソースコードを見てそれらを見つけただけです)、とにかく効果がないようです。
どんな助けでも大歓迎です。より多くの情報/コードが役立つ場合は、私に知らせてください。