简体   繁体   中英

How to query EF through the PK when using a generic class?

I'm trying to implement a generic class that will interact with a generic repository, and all is fine except for when I have to deal with getting objects out of the repository.

I'm going to have a virtual method in the generic class which will receive an int and I want to use that int to form a query to the repository that gets objects by their primary key. I have a feeling I need to work with the EntityKey property in EF, but not too sure how.

Anyway, here's what I'm trying to do in code, I hope someone will have suggestions on how to accomplish what I want:

public virtual T Get(int PrimaryKey) {
    this.Repository.Select(
        t =>
            (t.PRIMARYKEY == PrimaryKey)).Single();
}

I want to extend this class with more specialized classes, but since most of them only get their objects by querying the PK, it makes since to me to have a base method that can do it.

Thanks in advance for any suggestions!

UPDATE

So, here's where I've gotten with reflection, and I doubt its the proper way, but it somewhat works... I'm getting a NotSupportedException with the message 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. . Although I understand what it says and why it's saying, I'm not sure how to overcome it when my code looks like this:

private readonly string TEntityName = typeof(T).Name;

public virtual T Get(
    int PrimaryKey) {
    return this.Repository.Select(
        t =>
            (((int)t.GetType().GetProperties().Single(
                p =>
                    (p.Name == (this.TEntityName + "Id"))).GetValue(t, null)) == PrimaryKey)).Single();
}

Hoping that someone who knows how to use reflection, unlike me, can point me in the right direction. Thanks!

Retrieving an entity by a PK using EF requires an expression/predicate, like this:

Expression<Func<Order,bool>> predicate = x => x.OrderId == 1;
return ctx.Orders.Single(predicate);

There is no easy way (short of reflection or expression tree creation) to be able to dynamically create this predicate.

What you could do is accept the predicate as a parameter:

public virtual T Get(Expression<Func<T,bool>> predicate) {
    this.Repository.Select(predicate).Single();
}

Also make sure you put some generic constraints on T (either at the class/method level).

http://msdn.microsoft.com/en-us/library/bb738961.aspx is way to go. Then use http://msdn.microsoft.com/en-us/library/bb738607.aspx , spend some time in debugger and your misson is completed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM