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

C# 通用存储库是否需要在任何地方应用基本实体类?,c#,repository-pattern,onion-architecture,C#,Repository Pattern,Onion Architecture,我正在使用ASP.NET MVC和洋葱架构创建一个Intranet网站。我一直在实现存储库模式,但遇到了一个困难 假设我有一个包含IDDocument的文档表。这就是我的回购协议(只有一种方法): 然后,我的文档POCO变为: public class Document : BaseEntity{ //Properties here } 我的回购协议: class Repository<T> : IRepository<T> where T : BaseEnt

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

假设我有一个包含IDDocument的文档表。这就是我的回购协议(只有一种方法):

然后,我的文档POCO变为:

public class Document : BaseEntity{ 
   //Properties here
}
我的回购协议:

 class Repository<T> : IRepository<T> where T : BaseEntity
    {
        private readonly PrincipalServerContext context;
        private DbSet<T> entities;
        public T Get(long id)
        {
            return entities.SingleOrDefault(s => s.ID == id);//Here is my problem
        }
    }
类存储库:IRepository其中T:BaseEntity
{
私有只读PrincipalServerContext上下文;
私营DbSet实体;
公共不获取(长id)
{
返回entities.SingleOrDefault(s=>s.ID==ID);//这是我的问题
}
}
但是我不想理想地这样做。我喜欢通用repo,因为它允许我不对所有不同的表重复相同的代码(我有300+)。但拥有一个基本实体也意味着重组我已经做过的很多事情。 是否可能有一个通用的回购协议,您可以在没有这个BaseEntity类的情况下应用于任何POCO

感谢您的帮助

您正在调用该方法

它的第二个参数的类型为
Expression
,因此您可以根据需要使用as identifier属性手动构建表达式

简短示例:

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<Func<T, bool>>(equal, parameter);
    return entities.SingleOrDefault(predicate);
}
public无法获取(长id)
{
var idName=“ID”+typeof(T).Name;//对于文档,将是IDDocument
var parameter=Expression.parameter(id.GetType());
var property=Expression.property(参数,idName)
var idValue=Expression.Constant(id,id.GetType());
var equal=表达式.equal(属性,idValue);
var谓词=表达式.Lambda(等于,参数);
返回实体。SingleOrDefault(谓词);
}
假设您编写了lambda函数
(T obj)=>obj.IdProperty==id
。 这里的
obj
参数
idName
应该存储
“IdProperty”
字符串。
property
表示
obj.IdProperty
idValue
表示
id
时的值。
equal
表示调用该方法的
obj.IdProperty==id
,谓词表示整个表达式
(T obj)=>obj.IdProperty==id

它的第二个参数的类型为
Expression
,因此您可以根据需要使用as identifier属性手动构建表达式

简短示例:

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<Func<T, bool>>(equal, parameter);
    return entities.SingleOrDefault(predicate);
}
public无法获取(长id)
{
var idName=“ID”+typeof(T).Name;//对于文档,将是IDDocument
var parameter=Expression.parameter(id.GetType());
var property=Expression.property(参数,idName)
var idValue=Expression.Constant(id,id.GetType());
var equal=表达式.equal(属性,idValue);
var谓词=表达式.Lambda(等于,参数);
返回实体。SingleOrDefault(谓词);
}
假设您编写了lambda函数
(T obj)=>obj.IdProperty==id
。 这里的
obj
参数
idName
应该存储
“IdProperty”
字符串。
property
表示
obj.IdProperty
idValue
表示
id
时的值。
equal
表示
obj.IdProperty==id
,谓词表示整个表达式
(T obj)=>obj.IdProperty==id

您至少需要一个接口来为编译器提供有关
的信息,当您的泛型类采用
T:class
时,您希望您的代码如何知道
id
是什么?@DanielA.White好的,谢谢you@maccettura这就是我问题的全部内容…@Flexabustbergson在使用如果泛型必须是特定形状(即具有ID),则需要提供一个通用类型。无论这是接口、抽象类,还是其他类继承的常规类。在某些情况下,您需要找出所有类之间的共性,如果没有共性,那么您就不应该使用泛型来尝试并强制它们都是相同的(当然,除非您不需要访问泛型类中的任何成员/属性,否则它们实际上是什么形状都无关紧要)。您至少需要一个接口来向编译器提供有关
的信息。当泛型类采用
T:class
时,您希望您的代码如何知道
ID
是什么?@DanielA.White好的,谢谢you@maccettura好吧,这就是我问题的全部要点…@Flexabustbergson在使用必须是确定的泛型时形状(即有一个ID),您需要提供一个通用类型。无论这是接口、抽象类,还是其他类继承的常规类。在某些情况下,您需要找出所有类之间的共性,如果没有共性,那么您就不应该使用泛型来尝试并强制它们都是相同的(当然,除非您不需要访问泛型类中的任何成员/属性,否则它们实际上是什么形状都无关紧要)哇,这正是我要找的!谢谢你,先生!这是书签。这是我第一次看到表达式树以一种真正让它们变得有用的方式被解释。哇,这正是我想要的!谢谢你,先生!这是书签。这是我第一次看到表达式树被解释成一种真正有用的方式。
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<Func<T, bool>>(equal, parameter);
    return entities.SingleOrDefault(predicate);
}