我只是用Entity Framework弄溼了自己的腳,但是我對DBSet對象的一些行爲感到有些莫名其妙。當我調用Find()方法時,它似乎意識到我最近添加的(但尚未保存的)項目的集合,但是當我嘗試查詢DBSet時,它似乎只包含一直存在的項目。有沒有簡單的方法來解決這個問題?我包括一些代碼,我已經做了嘗試解決這個問題,但是當它開始通過從我的「添加」變更集的項目進行迭代,我得到這個錯誤:有沒有辦法在DBSet的查詢中包含本地緩存的項目?
"Unable to create a constant value of type EntityType. Only primitive types ('such as Int32, String, and Guid') are supported in this context."
internal DbContext Context { get; set; }
protected DbSet<T> DBSet { get; set; }
public virtual IEnumerable<T> Get(
Expression<Func<T, bool>> filter = null,
Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null,
bool ignoreCachedChanges = false)
{
IQueryable<T> oReturn = DBSet;
// This block is intended to adjust the queryable source to account for changes
if (!ignoreCachedChanges)
{
oReturn = oReturn.Except(Context.ChangeTracker.Entries<T>().Where(x => x.State == System.Data.EntityState.Deleted).Select(x => x.Entity));
oReturn = oReturn.Union(Context.ChangeTracker.Entries<T>().Where(x => x.State == System.Data.EntityState.Added).Select(x => x.Entity));
}
if (filter != null)
oReturn = oReturn.Where(filter);
if (orderBy != null)
return orderBy(oReturn).ToList();
else
return oReturn.ToList();
}
// NOTE: Get By ID uses Find which considers the queued-but-not-yet-applied changes
public virtual T GetByID(object id)
{
return DBSet.Find(id);
}
(在上下文有幫助的情況下,我這樣做是因爲我想設置一個單元測試,在其中填充我的(本地)上下文,以滿足特定測試環境的項目......我很快就不需要應用這些變化,因爲他們真的只適用於特定的測試,但我可以,如果需要的話...在這樣做,我很驚訝地發現,存儲庫不包括其查詢結果中的變化項目 - 除非我在做FindByID - 所以我也希望我能解決這種明顯的不一致性,或者g或者更好的理解爲什麼這是不可行的或者不是一個好主意? :))
謝謝!這讓我更好地理解發生了什麼。另外,如果您碰巧讀到:這是我的存儲庫查詢方法的明智方法嗎?我會傾向於認爲,因爲這個「離線」集合具有排隊的插入/刪除,它應該考慮那些(如DBSet.Find()似乎這樣做),但是有沒有理由不這樣做,我可能會忽略? – Steven
@Steven:'Find'非常特別。它只查詢主鍵。這可以在內存(第1步)和SQL中使用(第2步,如果第1步中沒有發現任何內容)。對於其他查詢,您必須記住,EF必須使用LINQ to Entities執行查詢,然後使用LINQ to Objects查詢來構建聯合。有些查詢甚至不能在LINQ to Objects(例如使用'EntityFunctions')時完成。或者相同的查詢可以有不同的行爲(例如,字符串搜索的區分大小寫)。僅使用一個查詢規範執行兩個查詢並非易事,也不可能。 – Slauma
(續)可能是它沒有按照您的意願實施的原因。這些也是您的通用泛型實現在ChangeTracker中構建DB查詢對象和對象的聯合的原因:您的'filter'應用於LTO或LTE時可能會給出不同的結果,或者它甚至不適用於LTO。我懷疑一個乾淨的通用實現是可能的。我會盡量避免你需要查詢'ChangeTracker'。如果你真的需要,不要嘗試一種通用的方法,只能在你的特定情況下進行,並且必須在特定的查詢中進行。 – Slauma