我目前有一个从基类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);
}
}
答案 0 :(得分:2)
您需要为TEntity
定义一个提供Type方法的界面。
public interface IEntity
{
string Type {get;}
}
然后,您可以将基类泛型参数约束到此,这将允许您的现有代码进行编译(因为编译器将知道任何TEntity
将具有Type
属性可用。)
abstract public class BaseRepository<TEntity>
where TEntity: IEntity
{
您还必须确保Instrument
(以及您实施的任何其他存储库类型)实现IEntity
:
public class Instrument : IEntity
{
public string Type
{
get { return "Instrument" }
}
}
答案 1 :(得分:0)
我做了一个小帮手,做了一些可能对你有用的事情。
基本上,您可以使用它从属性名称和值创建谓词。
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));