Shaokan
Shaokan

Reputation: 7684

C# MVC generic repository with custom column name

How can I achieve something like the following?

public interface IGenericRepository 
{
    int id { get; }

    T GetById<T>() where T : class
}

public class GenericRepository : IGenericRepository 
{
    //Some code here

    public T GetById<T>(int tid) where T : class 
    { 
        return from tbl in dataContext.GetTable<T> where tbl.id == tid select tbl;
    }
 }

And I would like to use this as follows:

GenericRepository gr = new GenericRepository();
Category cat = gr.GetById<Category>(15);

Of course, in this usage, tbl.id in the GenericRepository gives me an error.

SOLUTION

public class IHasId
{
    public int id { get; set; }
}

public interface IGenericRepository
{
    int id { get; }

    T GetById<T>(int id) where T : IHasId;
}

public class GenericRepository : IGenericRepository
{
    public int id
    {
        get { throw new NotImplementedException(); }
    } 

    public T GetById<T>(int id) where T : IHasId
    {
        return from tbl in dataContext.GetTable<T> where tbl.id == tid select tbl;
    }
}

And apart from these, DON'T forget to define this somewhere in your model:

public partial class Category : IHasId { }

And the usage is:

Repository rep = new Repository();
Category cat = rep.GetById<Category>(15);

Upvotes: 0

Views: 937

Answers (3)

dknaack
dknaack

Reputation: 60516

You get this error because you accept every class where T : class. A class don't have that property.

Create an abstract class or interface to make sure that this property exists and change where T : class to where T : IHasIdProperty.

Upvotes: 1

dknaack
dknaack

Reputation: 60516

public class IHasId
{
    public int id { get; set; }
}

public interface IGenericRepository<T>
{
    int id { get; }

    T GetById(int id);
}

public class GenericRepository<T> : IGenericRepository<T> where T : IHasId
{
    public int id
    {
        get { throw new NotImplementedException(); }
    }

    public T GetById(int id)
    {
        return from tbl in dataContext.GetTable<T> where tbl.id == tid select tbl;
    }
}

Upvotes: 1

Dave
Dave

Reputation: 3621

There's a few problems here - the first is that the generic type you're matching is a class, but a class doesn't have a property called 'id'. You need to have your Category class implement an interface that exposes an 'id' property:

public interface IIdentity
{
    int identity { get; set; }
}

public class Category : IIdentity
{
    public int identity{ get; set; }
}

I don't know why you've exposed 'id' as a property on the IGenericRepository interface - surely this is supposed to be a parameter passed to the find method (as indicated by your implementation). You also need to change the restriction on the 'GetById' method from:

where T : class

to something like

where T : IIdentity

using the interface I've suggested above.

Upvotes: 2

Related Questions