C# EntityFramework存储库模板-如何在模板类中编写GetByID lambda?

C# EntityFramework存储库模板-如何在模板类中编写GetByID lambda?,c#,entity-framework,templates,repository-pattern,C#,Entity Framework,Templates,Repository Pattern,我正在尝试为我目前正在从事的基于实体框架的项目编写一个通用的、适合大多数存储库模式的模板类。(高度简化的)接口是: internal interface IRepository<T> where T : class { T GetByID(int id); IEnumerable<T> GetAll(); IEnumerable<T> Query(Func<T, bool> filter); } 内部接口i假设,其中T:class {

我正在尝试为我目前正在从事的基于实体框架的项目编写一个通用的、适合大多数存储库模式的模板类。(高度简化的)接口是:

internal interface IRepository<T> where T : class
{
  T GetByID(int id);
  IEnumerable<T> GetAll();
  IEnumerable<T> Query(Func<T, bool> filter);
}
内部接口i假设,其中T:class
{
T GetByID(int-id);
IEnumerable GetAll();
IEnumerable查询(Func过滤器);
}
盖特比德被证明是凶手。在实施过程中:

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);
  }
公共类存储库:IRepository,IUnitOfWork其中T:class
{
//等等。。。
公共T GetByID(int-id)
{
返回this.ObjectSet.Single(t=>t.ID==ID);
}

t=>t.ID==ID是我正在努力解决的一个特殊问题。在没有特定于类的信息可用的模板类中编写lambda函数是否可能呢?

您只需创建一个包含ID属性的小接口,而不必限制为实现它的类型

编辑: 根据注释,如果您接受编译器不会帮助您确保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));
    }
}
公共类回购,其中T:class
{
私有IEnumerable All()
{
抛出新的NotImplementedException();
}
私有布尔过滤器id(动态输入,整数id)
{
返回输入。Id==Id;
}
公共T GetById(int-id)
{
返回这个.All().Single(t=>filteroid(t,id));
}
}

我定义了一个接口:

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),如:

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
{
//
///实现IDataRepository接口的抽象基类。
/// 
///POCO实体
公共抽象类数据存储库:IDataRepository
其中T:等级,身份
{

虽然我可以做一些类似| | public T GetSingle(filter)| |的事情,但如果可能的话,我更喜欢一个更简单的GetByID,因为每个绑定到存储库的类都有一个ID属性。到目前为止,我最接近解决方案的是返回查询(Function(x)CType(x,Object).ID=ID),其中查询是围绕datacontext的包装器。where(过滤器)。谢谢,+1。虽然它可以工作,但考虑到通用存储库模板的要点是简单和尽量减少冗余代码,我希望有一个答案不需要让我的所有实体类都继承自某个GenericWithID类。虽然这个问题的公认答案解决了我当时的问题,但我实际上已经使用了您最近提到的方法,并且更喜欢它。更改为接受此作为答案,因为它与我现在正在做的差不多,而且非常棒。T4 POCO生成器使所有生成的类实现了IEntity。。。
/// <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
{