我使用LinqKit用以下搜索功能的EntityFramework 4.0搜索庫:IQueryable的<T>與EntityObject使用泛型和接口(可能嗎?)
public IQueryable<T> Search<T>(Expression<Func<T, bool>> predicate)
where T : EntityObject
{
return _unitOfWork.ObjectSet<T>().AsExpandable().Where(predicate);
}
和使用IQueryable的返回值子集的另一個類查詢的方式使用布爾LinqKit PredicateBuilder表達式是不可能的:
public IQueryable<T> SubsetByUser<T>(IQueryable<T> set, User user)
where T : EntityObject
{
return set.Join(_searcher.Search<Metadatum>((o) => o.UserGUID == user.GUID),
arc => arc.GUID,
meta => meta.ElementGUID,
(arc, meta) => arc);
}
的這裏的問題是,「T」作爲EntityObject沒有定義GUID,所以我不能用這個。這種自然的反應是實際定義SubsetByUser()方法使用約束帶GUID屬性:
public IQueryable<T> SubsetByUser<T>(IQueryable<T> set, User user)
where T : IHaveMetadata
{
return set.Join(_searcher.Search<Metadatum>((o) => o.UserGUID == user.GUID),
arc => arc.GUID,
meta => meta.ElementGUID,
(arc, meta) => arc);
}
但是,這是行不通的。我正在使用LinqKit和Expandable()方法得到:
System.NotSupportedException: Unable to cast the type 'Oasis.DataModel.Arc' to
type 'Oasis.DataModel.Interfaces.IHaveMetadata'. LINQ to Entities only supports
casting Entity Data Model primitive types
我需要一個IQueryable來返回。我可以做一個假像這樣:
public IQueryable<T> SubsetByUser<T>(IQueryable<T> set, User user)
where T : EntityObject
{
return set.AsEnumerable()
.Join(_searcher.Search<Metadatum>((o) => o.UserGUID == user.GUID),
arc => arc.GUID,
meta => meta.ElementGUID,
(arc, meta) => arc)
.AsQueryable();
}
其中,當然,工作,但它也是,當然,蝙蝠屎瘋狂的事情。 (整個原因,我想是IQueryable的,直到我們最終不執行查詢
我甚至已經試過這樣:
public IQueryable<T> SubsetByUser<T>(IQueryable<T> set, User user)
where T : EntityObject
{
return set.Join(_searcher.Search<Metadatum>((o) => o.UserGUID == user.GUID),
arc => arc.GetType().GetProperty("GUID").GetValue(arc,null),
meta => meta.ElementGUID,
(arc, meta) => arc);
}
,它使用反射來獲得奔跑收藏 - 周圍的編譯器工作。錯誤我認爲這是相當聰明的,但它導致了LINQ例外:
System.NotSupportedException: LINQ to Entities does not recognize the
method 'System.Object GetValue(System.Object, System.Object[])' method,
and this method cannot be translated into a store expression.
我也可以嘗試改變搜索方法:
public IQueryable<T> Search<T>(Expression<Func<T, bool>> predicate)
where T : IRunElement
{
return _unitOfWork.ObjectSet<T>().AsExpandable().Where(predicate);
}
但是,這當然不會編譯,因爲IRunElement不是EntityObject,並且ObjectSet將T約束爲類。
最後一種可能性是簡單地讓所有的參數和返回值的IEnumerable:
public IEnumerable<T> SubsetByUser<T>(IEnumerable<T> set, User user)
where T : EntityObject
{
return set.Join(_searcher.Search<Metadatum>((o) => o.UserGUID == user.GUID),
arc => arc.GetType().GetProperty("GUID").GetValue(arc,null),
meta => meta.ElementGUID,
(arc, meta) => arc);
}
也可以工作,但是這又不允許我們拖延的實例化,直到結束。
因此,似乎有很少的事情可以做到這一點,而無需將所有東西都實例化爲IEnumerable,然後使用AsQueryable()返回它。有什麼方法可以將這些放在一起,我錯過了嗎?
是否可以顯示你如何用這個SubsetByUser功能(在那裏你會從你的查詢稱呼它)多一點點的代碼。試圖做類似的事情。 – AaronLS 2012-05-31 21:07:27
@AaronLS,我不再在這個項目上了,但基本上是-IIRC,set參數是來自另一個查詢的返回集。所以它只是_subsetContainer.SubsetByUser(_container.Search (謂詞),someUser); –
JohnMetta
2012-06-15 16:56:09