Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 泛型类需要访问Where子句中的属性_C#_Entity Framework_Generics - Fatal编程技术网

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

C# 泛型类需要访问Where子句中的属性,c#,entity-framework,generics,C#,Entity Framework,Generics,我目前有一个从基类BaseRepository继承的存储库,如下所示。当一个仪器需要它的类型时,它工作得很好。但是,我不想在派生类中定义GetByType,而是在BaseRepository中定义。显然,BaseRepository中的非抽象方法不起作用,因为它不知道什么是显式的。也就是说,它不知道I.类型是什么。我如何实现这一点 public class InstrumentRepository : BaseRepository<Instrument> { // overr

我目前有一个从基类BaseRepository继承的存储库,如下所示。当一个仪器需要它的类型时,它工作得很好。但是,我不想在派生类中定义GetByType,而是在BaseRepository中定义。显然,BaseRepository中的非抽象方法不起作用,因为它不知道什么是显式的。也就是说,它不知道I.类型是什么。我如何实现这一点

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); 
    }
}
公共类工具库:BaseRepository
{
//重写基类中的抽象方法
公共重写IEnumerable GetByType(字符串类型)
{
返回db.Instruments.Where(i=>i.Type==Type);
}
}
抽象公共类基存储库
{
publicMyDbContext数据库;
内部数据库集;
公共基本存储库()
{
db=新的MyDbContext();
//从给定的tenty创建一个DBSet
this.dbSet=db.Set();
}
//我现在有什么
抽象公共IEnumerable GetByType(字符串类型);
//我想要这样的东西,我会摆脱它
//抽象方法的应用。
公共IEnumerable GetByType(字符串类型)
{
//当然,这不会编译
返回dbSet.Where(i=>i.Type==Type);
}
}

您需要为提供类型方法的
tenty
定义一个接口

public interface IEntity 
{
     string Type {get;}
}
然后,可以将基类泛型参数约束到该参数,这将允许编译现有代码(因为编译器知道任何
TEntity
都将有一个
类型
属性可用)


我让一个小助手做了一些类似的事情,可能对你有用

实际上,您可以使用它从属性名和值创建谓词

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();
    }
public static Func MakeFilter(string _propertyName,object _value),其中tenty:class
{
变量类型=类型(强度);
var property=type.GetProperty(_propertyName);
var参数=表达式参数(类型为“p”);
var propertyAccess=Expression.MakeMemberAccess(参数,属性);
var constantValue=表达式常数(_值);
变量相等=表达式.Equal(propertyAccess,constantValue);
返回表达式.Lambda(相等,参数).Compile();
}

用法如下:
array.FirstOrDefault(LinqHelper.MakeFilter(itemName,valueToLookFor))

您不能将“Type”属性放入基类中吗?假设其他子类使用它,
.OfType()有什么问题?此扩展方法是在
IEnumerable
IQueryable
Object#GetType()
和比较类型而不是字符串上定义的。@KrisVandermotten
Type
是相关对象的一个属性,它实际上不是基于C类型进行过滤的。就是这样。作为补充说明,我还必须添加一个类约束,因为DbSet需要引用类型。谢谢
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();
    }