如何反映T为查询构建表达式树?

我正在尝试构建一个通用类来处理来自EF的实体。 这个类与存储库进行对话,但是这个类创建了发送到存储库的表达式。 无论如何,我只是想实现一个虚拟方法,它将作为常见查询的基础。 具体来说,它将接受一个int ,它只需要对相关实体的主键执行查询。

我一直在搞砸它,我已经建立了一个反映,可能会或可能不会。 我这样说是因为我得到一个带有LINQ to Entities消息的NotSupportedException无法识别方法’System.Object GetValue(System.Object,System.Object [])’方法,并且此方法无法转换为商店表达式。 那么我尝试了另一种方法,它产生了相同的exception,但LINQ表达式错误的节点类型’ArrayIndex’在LINQ to Entities中不受支持。 我知道这是因为EF不会像L2S那样解析表达式。

无论如何,我正在跳跃一个有更多经验的人可以指出我正确的方向。 我正在用我所做的两次尝试发布整个class级。

 public class Provider where T : class { protected readonly Repository Repository = null; private readonly string TEntityName = typeof(T).Name; [Inject] public Provider( Repository 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 GetAll() { return this.Repository.Select().ToList(); } protected virtual void Save() { this.Repository.Update(); } } 

更新 @Gabe

这是我的存储库类的样子:

 public class Repository where T : class { protected readonly ObjectContext ObjectContext = null; private readonly IObjectSet ObjectSet = null; [Inject] public Repository( ObjectContext ObjectContext) { this.ObjectContext = ObjectContext; this.ObjectSet = this.ObjectContext.CreateObjectSet(); } public virtual void Delete( T Entity) { this.ObjectSet.DeleteObject(Entity); } public virtual void Insert( T Entity) { this.ObjectSet.AddObject(Entity); } public virtual IQueryable Select() { return this.ObjectSet; } public virtual IQueryable Select( Expression<Func> Selector) { return this.ObjectSet.Where(Selector); } public virtual void Update() { this.ObjectContext.SaveChanges(); } } 

方法的名称基于SQL函数,而不是基于LINQ方法,我认为你对我的存储库的运行方式感到困惑。

正如Pauli所说,你需要手动创建Expression树,尽管在这种情况下不需要reflection。 以下是编写Get函数的方法:

 public virtual T Get( int PrimaryKey) { var param = Expression.Parameter(typeof(T)); // create expression for param => param.TEntityNameId == PrimaryKey var lambda = Expression.Lambda>( Expression.Equal( Expression.Property(param, TEntityName + "Id"), Expression.Constant(PrimaryKey)), param); return this.Repository.Single(lambda); } 

另请注意, GetAll函数不需要Selectreturn Repository.ToList(); 也会起作用。