通用存储库是否需要在任何地方应用基本实体类?

我正在使用ASP.NET MVC和Onion Architecture创建一个Intranet网站。 我一直在实现存储库模式,但我遇到了困难。

假设我有一个带有IDDocument的Document表。 那么这是我的回购(只有一种方法):

class Repository : IRepository where T : class { private readonly PrincipalServerContext context; private DbSet entities; //Constructor and stuff here public T Get(long id) { return entities.SingleOrDefault(s => s.IDDocument == id);//Here is my problem } } 

问题是我不能使用它,因为T不被识别为来自Document表。 解决方案是创建一个BaseEntity:

 public class BaseEntity{ public int ID{get;set;} } 

然后我的文件POCO变成:

 public class Document : BaseEntity{ //Properties here } 

而我的回购:

  class Repository : IRepository where T : BaseEntity { private readonly PrincipalServerContext context; private DbSet entities; public T Get(long id) { return entities.SingleOrDefault(s => s.ID == id);//Here is my problem } } 

我不想理想地这样做 。 我在通用仓库中喜欢的是它允许我不为所有不同的表重复相同的代码(我有300+)。 但拥有BaseEntity也意味着重组我已经做过的很多事情。 是否有可能在没有此BaseEntity类的情况下在任何POCO上应用Generic repo?

谢谢你的帮助

您正在调用Queryable.SingleOrDefault方法。

它的第二个参数具有Expression>类型Expression>因此您可以使用as title属性手动构建表达式。

简短的例子:

 public T Get(long id) { var idName = "ID" + typeof(T).Name; // For Document would be IDDocument var parameter = Expression.Parameter(id.GetType()); var property = Expression.Property(parameter, idName) var idValue = Expression.Constant(id, id.GetType()); var equal = Expression.Equal(property, idValue); var predicate = Expression.Lambda>(equal, parameter); return entities.SingleOrDefault(predicate); } 

想象一下你写了lambda函数(T obj) => obj.IdProperty == id 。 这里objparameteridName应该存储"IdProperty"字符串。 property表示obj.IdPropertyidValue表示id的值。 equal表示obj.IdProperty == id ,谓词表示整个表达式(T obj) => obj.IdProperty == id