EntityFrameworkでは、AddObjectを使用してコンテキストに追加されたばかりのオブジェクトを照会することは可能ですが、SaveChangesメソッドを呼び出す前に可能ですか?あなたはこのようなオブジェクトを照会することができますSaveChangesの前にAddObjectの後にオブジェクトを照会していますか?
おかげ
EntityFrameworkでは、AddObjectを使用してコンテキストに追加されたばかりのオブジェクトを照会することは可能ですが、SaveChangesメソッドを呼び出す前に可能ですか?あなたはこのようなオブジェクトを照会することができますSaveChangesの前にAddObjectの後にオブジェクトを照会していますか?
おかげ
、
context.ObjectStateManager.GetObjectStateEntries(EntityState.Added).Select(obj => obj.Entity).OfType<TheEntityType>()
これは、追加の状態にあるオブジェクトを照会します。他の州も欲しければ、他のすべての州をGetObjectStateEntries
メソッドに渡すことができます。
GetObjectStateEntries(EntityState.Added | EntityState.Modified | EntityState.Unchanged)
エンティティを永続化するには、通常、コンテキストに「DbSet
」というエンティティを追加します。
var bar = new Bar();
bar.Name = "foo";
var context = new Context();
context.Bars.Add(bar);
驚くべきことに、context.Bars
を照会、追加したエンティティは
var howMany = context.Bars.Count(b => b.Name == "foo");
// howMany == 0
を見つけることができないcontext.SaveChanges()
後、同じ行が1
DbSet
変更に気付かないと思わをもたらすであろう。例えば
それらがdbに保存されるまで。
幸いなことに、各DbSet
はDbSet
そのもののような役割を果たしLocal
性質を持っているが、それはあなたがまた、エンティティを追加するLocal
を使用することができます
var howMany = context.Bars.Local.Count(b => b.Name == "foo");
// howMany == 1
すべてのメモリ内の操作を反映
context.Bars.Local.Add(bar);
とEntity Frameworkの奇妙な動作を取り除く。
hibernateの一時インスタンスでは、すでにコンテキストにアタッチされています。ただ、このEFの制限に遭遇しました。
私はObjectSet
と一時的なエンティティObjectSet.Local
を交差/結合できませんでしたが、私たちのユースケースでは、以下のfindメソッドで十分です。
私たちのケースでは、我々は反復中に独自の基準に応じて怠惰ないくつかのエンティティを作成
Findメソッド
あなたがのような方法で作成することができリポジトリパターンを使用している場合:
をpublic interface IRepository<T> where T : class, IEntity
{
/// <summary>
/// Finds the unique Entity with the given predicate.
/// Depending on implementation also checks transient/local (unsaved) Entities.
/// </summary>
/// <param name="predicate"></param>
/// <returns></returns>
IQueryable<T> FindAll(Expression<Func<T, bool>> predicate);
}
public class EfRepository<T> : IRepository<T> where T : class, IEntity
{
protected readonly ObjectContext context;
protected readonly ObjectSet<T> objectSet;
/// <summary>
/// Creates a new repository of the given context.
/// </summary>
/// <param name="context"></param>
public EfRepository(ObjectContext context)
{
if (context == null)
throw new ArgumentException("Context must not be null.");
this.context = context;
this.objectSet = context.CreateObjectSet<T>();
}
/// <summary>
/// Also takes local context into consideration for unsaved changes
/// </summary>
/// <param name="predicate"></param>
/// <returns></returns>
public T Find(Expression<Func<T, bool>> predicate)
{
T result = this.objectSet.Where(predicate).FirstOrDefault();
if (result == null)
result = this.objectSet.Local().Where(predicate).FirstOrDefault();
return result;
}
}
これは、追加されたが保存されていないアイテムとデータベースのアイテムの両方を返しますか? – BlackICE
'context.Bars.Local'はデータベースから' context.Bars'がロードされるまでは最初は空です。メモリ内の項目とデータベースの項目の両方を持つことができます。大規模なデータセットでLocalを使用することは推奨されません。ローカルに関する詳細情報:https://msdn.microsoft.com/en-us/data/jj592872 – Aximili
これはEF過去4版に固有のものですか?私は 'ObjectSet'に' Local'プロパティを持っていませんが、 'DbSet'と' DbContext'ではなく 'ObjectSet'と' ObjectContext'オブジェクトも持っています。 –