我試圖建立一個通用類來處理來自EF的實體。這個類與儲存庫對話,但是這個類創建發送到儲存庫的表達式。無論如何,我只是試圖實現一個虛擬方法,它將作爲普通查詢的基礎。具體來說,它將接受一個int
,它只需要對相關實體的主鍵執行查詢。如何反思T爲查詢構建表達式樹?
我一直在使用它,我已經建立了一個可能或可能不起作用的反射。我說因爲我得到一個NotSupportedException
消息LINQ to Entities不識別方法'System.Object GetValue(System.Object,System.Object [])'方法,並且此方法不能轉換爲存儲表達式。因此,然後我嘗試了另一種方法,它產生了相同的異常,但與的錯誤LINQ表達式節點類型'ArrayIndex'在LINQ to Entities中不受支持。我知道這是因爲EF不會像L2S那樣解析表達式。
無論如何,我跳過一個有更多經驗的人可以指出我正確的方向。我在發佈兩個嘗試的過程中發佈了整個課程。
public class Provider<T> where T : class {
protected readonly Repository<T> Repository = null;
private readonly string TEntityName = typeof(T).Name;
[Inject]
public Provider(
Repository<T> Repository) {
this.Repository = Repository;
}
public virtual void Add(
T TEntity) {
this.Repository.Insert(TEntity);
}
public virtual T Get(
int PrimaryKey) {
// The LINQ expression node type 'ArrayIndex' is not supported in
// LINQ to Entities.
return this.Repository.Select(
t =>
(((int)(t as EntityObject).EntityKey.EntityKeyValues[0].Value) == PrimaryKey)).Single();
// 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.
return this.Repository.Select(
t =>
(((int)t.GetType().GetProperties().Single(
p =>
(p.Name == (this.TEntityName + "Id"))).GetValue(t, null)) == PrimaryKey)).Single();
}
public virtual IList<T> GetAll() {
return this.Repository.Select().ToList();
}
protected virtual void Save() {
this.Repository.Update();
}
}
UPDATE爲@Gabe
這是我的倉庫類的樣子:
public class Repository<T> where T : class {
protected readonly ObjectContext ObjectContext = null;
private readonly IObjectSet<T> ObjectSet = null;
[Inject]
public Repository(
ObjectContext ObjectContext) {
this.ObjectContext = ObjectContext;
this.ObjectSet = this.ObjectContext.CreateObjectSet<T>();
}
public virtual void Delete(
T Entity) {
this.ObjectSet.DeleteObject(Entity);
}
public virtual void Insert(
T Entity) {
this.ObjectSet.AddObject(Entity);
}
public virtual IQueryable<T> Select() {
return this.ObjectSet;
}
public virtual IQueryable<T> Select(
Expression<Func<T, bool>> Selector) {
return this.ObjectSet.Where(Selector);
}
public virtual void Update() {
this.ObjectContext.SaveChanges();
}
}
的方法的名稱是基於SQL的功能,而不是在LINQ方法,這是我認爲你對我的存儲庫功能有困惑的地方。
它看起來像你認爲`Select`基於`Get`函數完成`Where`的工作。 「Where」的作用是選擇要返回的行(例如具有匹配主鍵的行),而「Select」只是選擇返回哪些列(通常全部在EF中)。 – Gabe 2011-01-08 07:42:25
@加貝,請看我上面的更新,我解釋了爲什麼。 – Gup3rSuR4c 2011-01-08 22:45:31