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

时间:2010-05-31 06:12:53

标签: 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);
}

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 =&gt; t.ID == id是我正在努力的特定位。甚至可以在模板类中编写类似lambda的函数,而不会有特定于类的信息吗?

2 个答案:

答案 0 :(得分:4)

我已经定义了一个界面:

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(long 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
{

答案 1 :(得分: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));
    }
}