在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
似乎沒有意識到的變化直到他們堅持數據庫。
幸運的是,每個DbSet
有Local
財產,它如同DbSet
本身,但它反映了內存中的所有操作
var howMany = context.Bars.Local.Count(b => b.Name == "foo");
// howMany == 1
您還可以使用Local
添加實體
context.Bars.Local.Add(bar);
和擺脫Entity Framework的怪異行爲。
在hibernate中,瞬態實例已經連接到上下文。只是偶然發現了EF限制。
我沒有設法將ObjectSet
與其瞬態實體ObjectSet.Local
相交/聯合,但對於我們的用例,下面的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'。它可以包含內存中的項目和來自數據庫的項目。不建議在大型數據集上使用本地。有關本地的更多信息:https://msdn.microsoft.com/en-us/data/jj592872 – Aximili
這是特定於EF過去4版本的嗎?我的ObjectSet沒有'Local'屬性,但我也有'ObjectSet'和'ObjectContext'對象,而不是'DbSet'和'DbContext'。 –