How to reflect over T to build an expression tree for a query?

Posted by Alex on Stack Overflow See other posts from Stack Overflow or by Alex
Published on 2011-01-08T06:47:38Z Indexed on 2011/01/08 6:53 UTC
Read the original article Hit count: 167

Hi all, I'm trying to build a generic class to work with entities from EF. This class talks to repositories, but it's this class that creates the expressions sent to the repositories. Anyway, I'm just trying to implement one virtual method that will act as a base for common querying. Specifically, it will accept a an int and it only needs to perform a query over the primary key of the entity in question.

I've been screwing around with it and I've built a reflection which may or may not work. I say that because I get a NotSupportedException with a message of 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. So then I tried another approach and it produced the same exception but with the error of The LINQ expression node type 'ArrayIndex' is not supported in LINQ to Entities. I know it's because EF will not parse the expression the way L2S will.

Anyway, I'm hopping someone with a bit more experience can point me into the right direction on this. I'm posting the entire class with both attempts I've made.

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();
    }
}

© Stack Overflow or respective owner

Related posts about c#

Related posts about LINQ