Yaron Levi
Yaron Levi

Reputation: 13079

Entity Framework 4 - Generic method for retrieving entity by ID

I am writing method for fetching single entities by their ID :

public Customer GetCustomer(int i_CustomerID)
{
  return (from c in context.CustomerSet 
         where c.Id == i_CustomerID 
        select c).SingleOrDefault();            
}

public Movie GetMovie(int i_MovieID)
{
  return (from m in context.MovieSet 
         where m.Id == i_MovieID 
        select m).SingleOrDefault();
}

But I have many entities and this code repeats itself. I want to write a method like this:

public T GetEntityByID<T>(int i_EntityID)
{
  return (from e in context.T_Set 
         where e.Id == i_EntityID 
        select e).SingleOrDefault();
}

Is there a way to achieve that ?

Upvotes: 1

Views: 3489

Answers (3)

Rob
Rob

Reputation: 10248

I haven't actually executed this but it compiles and is probably something along the lines of what you are trying to achieve:

    public static void Testing()
    {
        SelectEntity<MyObject>(r => r.MyObjectId == 1);
    }

    public static T SelectEntity<T>(Expression<Func<T, bool>> expression) where T : EntityObject
    {
        MyContext db = new MyContext();
        return db.CreateObjectSet<T>().SingleOrDefault(expression);
    }

Upvotes: 3

Ladislav Mrnka
Ladislav Mrnka

Reputation: 364249

If you know that your generic repository will be always used with entity types which have PK with the same name and the same type you can simply define interface like this:

public interface IEntity
{
    int Id { get; }
}

and either implement this interface in partial part of your generated entities or modify T4 template to include it automatically. Your repository will be then defined as:

public interface IRepository<TEntity> where T : IEntity
{
    ...
}

If the type of PK can change but the name is still the same you can improve the entity interface to:

public interface IEntity<TKey> 
{
    TKey Id { get; set; }
}

and the definition of repository will be:

public interface IRepository<TEntity, TKey> where TEntity : IEntity<TKey>
{
    ...
}

If you want generic repository which is able to work with entities with different PK's name and type check this answer. That solution should probably also work (or with small modification) with composite PKs.

Upvotes: 0

Carlo V. Dango
Carlo V. Dango

Reputation: 13832

The problem is that there is no common super type that has the relevant properties that you seek. It is easy, however, to code generate your fetch methods using the in-built T4 code generation tool that EF is using. Here is a good link on how to hook in and generate the sort of code you need.

http://msdn.microsoft.com/en-us/data/gg558520

Upvotes: 1

Related Questions