2011-08-09 30 views

回答

10

您可以查詢這樣的對象,

context.ObjectStateManager.GetObjectStateEntries(EntityState.Added).Select(obj => obj.Entity).OfType<TheEntityType>() 

這將查詢其在加狀態的對象。如果你想要其他狀態,你可以通過所有其他狀態GetObjectStateEntries這樣的方法。

GetObjectStateEntries(EntityState.Added | EntityState.Modified | EntityState.Unchanged) 
23

要堅持一個實體,您通常會在上下文中將它添加到它的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似乎沒有意識到的變化直到他們堅持數據庫。

幸運的是,每個DbSetLocal財產,它如同DbSet本身,但它反映了內存中的所有操作

var howMany = context.Bars.Local.Count(b => b.Name == "foo"); 
// howMany == 1 

您還可以使用Local添加實體

context.Bars.Local.Add(bar); 

和擺脫Entity Framework的怪異行爲。

+3

這是否會返回已添加但尚未保存的項目和來自數據庫的項目? – BlackICE

+0

'context.Bars.Local'最初是空的,直到從數據庫加載'context.Bars'。它可以包含內存中的項目和來自數據庫的項目。不建議在大型數據集上使用本地。有關本地的更多信息:https://msdn.microsoft.com/en-us/data/jj592872 – Aximili

+0

這是特定於EF過去4版本的嗎?我的ObjectSet沒有'Local'屬性,但我也有'ObjectSet'和'ObjectContext'對象,而不是'DbSet'和'DbContext'。 –

1

在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; 
    } 
} 
相關問題