泛型类需要访问Where子句中的属性
本文关键字:属性 子句 Where 访问 泛型类 | 更新日期: 2023-09-27 17:50:44
我目前有一个继承自基类BaseRepository的存储库,如下所示。当一个仪器被它的类型所需要时,这工作得很好。但是,我不想在派生类中定义GetByType,而是在BaseRepository中定义。显然,BaseRepository中的非抽象方法不能工作,因为它不知道TEntity中有什么。也就是说,它不知道i。type是什么。我该如何实现呢?
public class InstrumentRepository : BaseRepository<Instrument>
{
// overrides the ABSTRACT method in the base class
public override IEnumerable<Instrument> GetByType(string type)
{
return db.Instruments.Where(i => i.Type == type);
}
}
abstract public class BaseRepository<TEntity>
{
publicMyDbContext db;
internal DbSet<TEntity> dbSet;
public BaseRepository()
{
db = new MyDbContext();
// create a DBSet from the given TEntity
this.dbSet = db.Set<TEntity>();
}
// what I have now
abstract public IEnumerable<TEntity> GetByType(string type);
// I want something like this instead, and I would get rid
// of the abstract method.
public IEnumerable<TEntity> GetByType(string type)
{
// of course this doesn't compile
return dbSet.Where(i => i.Type == type);
}
}
您需要为您的TEntity
定义一个提供Type方法的接口。
public interface IEntity
{
string Type {get;}
}
你可以约束你的基类泛型参数为this,这将允许你现有的代码编译(因为编译器将知道任何TEntity
将有一个Type
属性可用)。
abstract public class BaseRepository<TEntity>
where TEntity: IEntity
{
您还必须确保Instrument
(以及您实现的任何其他存储库类型)实现IEntity
:
public class Instrument : IEntity
{
public string Type
{
get { return "Instrument" }
}
}
我做了一个小助手来做类似的事情,可能对你有用。
本质上是用它来从属性名和值创建谓词。
public static Func<TEntity, bool> MakeFilter<TEntity>(string _propertyName, object _value) where TEntity : class
{
var type = typeof(TEntity);
var property = type.GetProperty(_propertyName);
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var constantValue = Expression.Constant(_value);
var equality = Expression.Equal(propertyAccess, constantValue);
return Expression.Lambda<Func<TEntity, bool>>(equality, parameter).Compile();
}
用法类似:array.FirstOrDefault(LinqHelper.MakeFilter<YourType>(itemName,valueToLookFor));