泛型类需要访问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); 
    }
}

泛型类需要访问Where子句中的属性

您需要为您的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));