我正在尝试为我正在处理的基于实体框架的项目编写一个通用的,适合最多的存储库模式模板类。 (严重简化的)界面是:
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的函数,而不会有特定于类的信息吗?
答案 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));
}
}