我试图建立一个通用类来处理来自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