带接口的C#MVC通用存储库类

Sha*_*kan 1 c# generics asp.net-mvc inheritance repository

我怎样才能实现类似下面的例子呢?

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;
   }
}
Run Code Online (Sandbox Code Playgroud)

我想用这个如下:

GenericRepository gr = new GenericRepository();
Category cat = gr.GetById<Category>(15);
Run Code Online (Sandbox Code Playgroud)

当然这个代码不起作用,因为如果我定义T : class那么该tbl.id部分将无法工作.但当然,应该有一种方法来实现这一点.

UPDATE

考虑到driis的回答,我正在做以下事情,但我仍然无法做到这一点:

public interface IEntity
{
    int id { get; }
}

public interface IGenericRepository : IEntity
{
    T GetById<T>(int id);
}

public class GenericRepository : IGenericRepository
{
    public T GetById<T>(int id) {
    return from tbl in dataContext.GetTable<T> where tbl.id == tid select tbl;
    }
}
Run Code Online (Sandbox Code Playgroud)

在这一点上tbl.id工作,但是dataContext.GetTable<T>给了我一个错误.

dri*_*iis 5

您可以 T 约束为包含ID的类型,您可能需要一个接口:

public interface IEntity 
{ 
    int Id { get; }
}
Run Code Online (Sandbox Code Playgroud)

然后将您的泛型方法声明为:

public IQueryable<T> GetById<T>(int tid) where T : IEntity
{ 
   return from tbl in dataContext.GetTable<T> where tbl.id == tid select tbl;
}
Run Code Online (Sandbox Code Playgroud)

当然,您需要为所有实体实现IEntity.我猜你正在使用Linq2Sql或类似的,在这种情况下你可以只做一个包含接口实现的部分类定义.