2010-05-31 58 views
3

我正在尝试为我目前正在开发的基于实体框架的项目编写一个通用的最适合大多数存储库模式的模板类。在(重简化)接口是:EntityFramework存储库模板 - 如何在模板类中编写GetByID lambda?

internal interface IRepository<T> where T : class 
{ 
    T GetByID(int id); 
    IEnumerable<T> GetAll(); 
    IEnumerable<T> Query(Func<T, bool> filter); 
} 

GetByID被证明是杀手。在执行中:

public class Repository<T> : IRepository<T>,IUnitOfWork<T> where T : class 
{ 
    // etc... 
    public T GetByID(int id) 
    { 
    return this.ObjectSet.Single<T>(t=>t.ID == id); 
    } 

t => t.ID == id是我努力的特定位。是否有可能在没有类特定信息可用的模板类中编写像那样的lambda函数?

+0

虽然我可以做类似||的事情public T GetSingle( filter)||如果可能的话,我真的更喜欢更简单的GetByID,因为每个存储库绑定的类将作为一个坚实的规则拥有一个ID属性。 – nathanchere 2010-05-31 06:47:05

+0

到目前为止最接近的解决方案是返回查询(函数(x)CType(x,Object).ID = ID)其中查询是datacontext.Where(过滤器)的包装。 – nathanchere 2010-06-02 03:49:54

回答

4

我VE定义的接口:

public interface IIdEntity 
{ 
    long Id { get; set; } 
} 


和改性产生我POCO类的T4模板,这样所有的类必须实现公共接口的IIdentity接口。

像这样:

using System.Diagnostics.CodeAnalysis; 
public partial class User : IIdEntity 
{ 
    public virtual long Id 
    { 
     get; 
     set; 
    } 

通过这种修改,我可以写一个通用GetById(长ID),如:

public T GetById(long id) 
{ 
    return Single(e => e.Id == id); 
} 

的IRepository定义如下:

/// <summary> 
/// Abstract Base class which implements IDataRepository interface. 
/// </summary> 
/// <typeparam name="T">A POCO entity</typeparam> 
public abstract class DataRepository<T> : IDataRepository<T> 
    where T : class, IIdEntity 
{ 
+0

虽然这个问题的接受答案当时解决了我的问题,但我实际上使用了最近提到的方法,并且更喜欢它。 – nathanchere 2010-10-09 07:50:57

+0

更改为接受此作为答案,因为它几乎是我现在正在做的,这很好。使所有生成的类实现IEntity的T4 POCO生成器... – nathanchere 2010-11-07 12:00:08

2

您可以创建一个包含Id属性的小接口,并将T限制为实现它的类型。

编辑: 基础上的评论,如果你接受这个事实,编译器不会成为帮助您确保ID属性确实存在,你也许能够做这样的事情:

public class Repo<T> where T : class 
{ 
    private IEnumerable<T> All() 
    { 
     throw new NotImplementedException(); 
    } 

    private bool FilterOnId(dynamic input, int id) 
    { 
     return input.Id == id; 
    } 

    public T GetById(int id) 
    { 
     return this.All().Single(t => FilterOnId(t, id)); 
    } 
} 
+0

谢谢,+1。虽然它有效,但由于通用存储库模板的要点是简单并且最大限度地减少了冗余代码,所以我希望有一个答案不需要使所有实体类都从某些GenericWithID类继承。 – nathanchere 2010-06-01 23:26:11