[英]Entity Framework generic Where for entities that inherit from a specific class
Here I have a generic Repository class I copied from a tutorial page, but specifically my problem is on the two last functions. 在这里,我有一个通用的Repository类,该类是从教程页面复制的,但是具体来说,我的问题在于最后两个函数。 On my project I have several catalog entities that inherit from CRUDProperties class and there is a property "Activo" in all of them, what I currently want to do is that if the entity inherits from CRUDProperties class I get all the entities with Activo property on true, and if they do not inherit from that class it just gets all entities.
在我的项目中,我有几个继承自CRUDProperties类的目录实体,并且所有实体中都有一个属性“ Activo”,我现在要做的是,如果该实体继承自CRUDProperties类,则将所有具有Activo属性的实体是的,如果它们不从该类继承,则仅获取所有实体。 But the compiler throws an error stating T is already defined.
但是编译器抛出错误,表明T已经定义。 What should I do?
我该怎么办?
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();
}
}
The compiler complains about the ambiguous naming of the type parameters. 编译器抱怨类型参数的命名不明确。 The class already has a type parameter named
T
, so in the context of the class that type parameter name is already "taken". 该类已经有一个名为
T
的类型参数,因此在类的上下文中,该类型参数名称已被“采用”。
But you should be able to accomplish what you want to do simply by renaming the type parameter for the method to something else than T
, so your changed method could look like this: 但是您应该能够简单地通过将方法的类型参数重命名为
T
其他东西来完成您想做的事情,因此更改后的方法看起来像这样:
public virtual IList<TCrud> GetAll<TCrud>() where TCrud : CRUDProperties
{
return context.Set<TCrud>().Where(c => c.Activo).ToList();
}
Note: I assume here that CRUDProperties
is a class... If it is an interface then you'll also need to copy the class
constraint to the method (ie change it to where TCrud : class, CRUDProperties
) 注意:我在这里假设
CRUDProperties
是一个类...如果它是一个接口,那么您还需要将class
约束复制到方法中(即,将其更改为where TCrud : class, CRUDProperties
)
using this method you can pass custom where clause to to your GetAll Method 使用此方法,您可以将自定义where子句传递给GetAll方法
public virtual IList<T> GetAll<T>(Expression<Func<T, bool>> predicate)
{
return context.Set<T>().Where(predicate).ToList();
}
In this method we first check if the T type have Activo property, If find this property so we create a custom expression tree and replace with default predicate that returns all records, this function only returns records that have true value in activo property. 在此方法中,我们首先检查T类型是否具有Activo属性,如果找到此属性,则我们创建一个自定义表达式树并替换为返回所有记录的默认谓词,此函数仅返回activo属性中值为true的记录。
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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.