C# 实体框架泛型,其中用于从特定类继承的实体

C# 实体框架泛型,其中用于从特定类继承的实体,c#,entity-framework,repository-pattern,C#,Entity Framework,Repository Pattern,这里我有一个从教程页面复制的通用存储库类,但具体来说,我的问题在于最后两个函数。在我的项目中,我有几个从CRUDProperties类继承的目录实体,所有这些实体中都有一个属性Activo,我当前想做的是,如果实体从CRUDProperties类继承,我会得到所有Activo属性为true的实体,如果它们不从该类继承,它只会得到所有实体。但是编译器抛出一个错误,声明T已经定义。我该怎么办 public class Repository<T> where T : class {

这里我有一个从教程页面复制的通用存储库类,但具体来说,我的问题在于最后两个函数。在我的项目中,我有几个从CRUDProperties类继承的目录实体,所有这些实体中都有一个属性Activo,我当前想做的是,如果实体从CRUDProperties类继承,我会得到所有Activo属性为true的实体,如果它们不从该类继承,它只会得到所有实体。但是编译器抛出一个错误,声明T已经定义。我该怎么办

public class Repository<T> where T : class
{
    private readonly projectEntities context;
    private IDbSet<T> entities;
    string errorMessage = string.Empty;

    public Repository(projectEntities context)
    {
        this.context = context;
    }

    public T GetById(object id)
    {
        return context.Set<T>().Find(id);
    }

    // This is the function that throws me a compilation error
    public virtual IList<T> GetAll<T>() where T : CRUDProperties
    {
        return context.Set<T>().Where(c => c.Activo).ToList();
    }

    public virtual IList<T> GetAll()
    {
        return context.Set<T>().ToList();
    }
}

使用此方法,可以将自定义where子句传递给GetAll方法

public virtual IList<T> GetAll<T>(Expression<Func<T, bool>> predicate)
{
    return context.Set<T>().Where(predicate).ToList();
}
在这个方法中,我们首先检查T类型是否有Activo属性,如果找到这个属性,那么我们创建一个自定义表达式树并替换为返回所有记录的默认谓词,这个函数只返回Activo属性中具有真值的记录

public virtual IList<T> GetAll<T>()
{
    Expression<Func<T, bool>> predicate = t => true;
    if(typeof(T).GetProperty("Activo") != null)
    {

        var epx = Expression.Parameter(typeof(T), "x");
        Expression left =  Expression.PropertyOrField(epx, "Activo");
        Expression right = Expression.Constant(true);
        Expression e1 = Expression.Equal(left, right);

        predicate = Expression.Lambda<Func<T, bool>>(e1, new ParameterExpression[] { epx });
    }
    return context.Set<T>().Where(predicate);
}

编译器抱怨类型参数的命名不明确。该类已经有一个名为T的类型参数,因此在该类的上下文中,该类型参数名称已经被采用

但是,您只需将方法的类型参数重命名为T以外的值,就可以完成您想要完成的任务,因此更改后的方法可能如下所示:

public virtual IList<TCrud> GetAll<TCrud>() where TCrud : CRUDProperties
{
    return context.Set<TCrud>().Where(c => c.Activo).ToList();
}

注意:这里我假设CRUDProperties是一个类。。。如果它是一个接口,那么您还需要将类约束复制到方法,即将其更改为TCrud:class,CRUDProperties

您在周围的类存储库中已经有一个类型参数T。如果要向该类中的方法添加新的/不同的类型参数,则需要为该类型参数指定一个不同的名称。@bassfader,以便可以为其分配任何其他字母,如果我希望它尽可能通用的话?这似乎非常有用,但是,当实体从特定类继承时,有没有一种方法可以自动应用谓词?这主要是我的意图。使用反射,检查您的泛型类型是否具有Activo属性为该属性生成谓词,并将其用作where cluase您可以用一个示例扩展您的答案吗?我已经找到了如何获取实体是否从类继承,但我无法访问实体属性