C# 具有动态特性的linqc滤波器

C# 具有动态特性的linqc滤波器,c#,entity-framework,linq,properties,C#,Entity Framework,Linq,Properties,我有一份财产清单 string[] strings = { "State", "Name","Location" }; 它们都在类型为string的测试对象中,我需要先循环抛出它们,然后在属性等于OK时过滤数据 这是我的代码片段 for (int x=0;x<strings.Length;x++) { // PropertyDescriptor prop = TypeDescriptor.GetProperties(typeof(Test)).Find(strings[x

我有一份财产清单

string[] strings =
{
    "State", "Name","Location"
};
它们都在类型为string的测试对象中,我需要先循环抛出它们,然后在属性等于OK时过滤数据

这是我的代码片段

for (int x=0;x<strings.Length;x++)
{
    // PropertyDescriptor prop = TypeDescriptor.GetProperties(typeof(Test)).Find(strings[x],true);                                               

    var miss = _unityOfWork.TestRepository.Get(i =>
                   i.GetType().GetProperty(strings[x]).Equals("OK") )
                   .Select().toList()
此代码返回以下异常:

LINQ to Entities无法识别“System.Reflection.PropertyInfo GetRuntimePropertySystem.Type,System.String”方法,此方法无法转换为存储表达式


我需要用数组中的属性名过滤列表

您可以这样做,但不确定确切的语法,但想法是:

var miss = _unityOfWork.TestRepository.Get()

                   .Where(i => i.GetType().GetProperty(strings[x]).Equals("OK"))
                   .toList()
编辑: 正确的选择应该是

var miss = _unityOfWork.TestRepository
                .ToList()
                .Where(i => i.GetType().GetProperty(strings[x]).Equals("OK"))
                .toList()

您可以这样做,但不确定确切的语法,但想法是:

var miss = _unityOfWork.TestRepository.Get()

                   .Where(i => i.GetType().GetProperty(strings[x]).Equals("OK"))
                   .toList()
编辑: 正确的选择应该是

var miss = _unityOfWork.TestRepository
                .ToList()
                .Where(i => i.GetType().GetProperty(strings[x]).Equals("OK"))
                .toList()

您可能会执行以下操作:

public string ValidateProperty<T>(T parameter)
{
     var properties = typeof(...).GetProperties();
     foreach(var property in properties)
          if(property == parameter)
              return "OK";

     return "FAIL";
}   

var content = collection.Get().Where(property => ValidateProperty(property.Name.Value) == "OK" && ValidateProperty(property.State.Value) == "OK");

没有时间检查语法,但这应该允许您比较所有语法。陷阱在于每次调用都会生成一个PropertyInfo数组。一个想法或一种不同的方法,但不确定它对您的实施是否可行。

您可能会执行以下操作:

public string ValidateProperty<T>(T parameter)
{
     var properties = typeof(...).GetProperties();
     foreach(var property in properties)
          if(property == parameter)
              return "OK";

     return "FAIL";
}   

var content = collection.Get().Where(property => ValidateProperty(property.Name.Value) == "OK" && ValidateProperty(property.State.Value) == "OK");

没有时间检查语法,但这应该允许您比较所有语法。陷阱在于每次调用都会生成一个PropertyInfo数组。一个想法或一种不同的方法,但不确定它对您的实现是否可行。

以下是我可能会如何做。。。简单明了,无反射,开关有两个功能:1防止未知字段,2为每种情况应用适当的条件

var strings = new[] { "State", "Name", "Location" };

var result = _unityOfWork.TestRepository.GetAll().AsQueryable();
// you may need to tweak the above before it works

foreach (var field in strings)
{
    switch (field)
    {
        case "State":
            result = result.Where(x => x.State == "OK");
            break;
        case "Name":
            result = result.Where(x => x.Name == "OK");
            break;
        case "Location":
            result = result.Where(x => x.Location == "OK");
            break;
    }
}

return result;   // if needed, add .ToList() or .ToArray() 

下面是我可能会怎么做。。。简单明了,无反射,开关有两个功能:1防止未知字段,2为每种情况应用适当的条件

var strings = new[] { "State", "Name", "Location" };

var result = _unityOfWork.TestRepository.GetAll().AsQueryable();
// you may need to tweak the above before it works

foreach (var field in strings)
{
    switch (field)
    {
        case "State":
            result = result.Where(x => x.State == "OK");
            break;
        case "Name":
            result = result.Where(x => x.Name == "OK");
            break;
        case "Location":
            result = result.Where(x => x.Location == "OK");
            break;
    }
}

return result;   // if needed, add .ToList() or .ToArray() 

由于OP指示属性始终相同,请尝试以下操作:

var miss = _unitOfWork.TestRepository
                      .Where(m => m.State == "OK" || m.Name == "OK" || m.Location == "OK");

由于OP指示属性始终相同,请尝试以下操作:

var miss = _unitOfWork.TestRepository
                      .Where(m => m.State == "OK" || m.Name == "OK" || m.Location == "OK");

您的测试存储库到底是什么?它是如何实现的?我想你的意思是说属性值何时等于OK,对吗?@EduardMalakhov它是从GenericRepositoryLINQ继承的。Linq正在尝试将表达式I.GetType.GetPropertystrings[x].EqualsOK转换为数据库查询,通常是SQL,这是错误中的存储表达式部分。但是,第一个支持.NET反射的数据库尚未发明…@wdosanjos对,测试类有3个属性需要验证,当这些属性等于OK时,您的测试存储库到底是什么?它是如何实现的?我想你的意思是说属性值何时等于OK,对吗?@EduardMalakhov它是从GenericRepositoryLINQ继承的。Linq正在尝试将表达式I.GetType.GetPropertystrings[x].EqualsOK转换为数据库查询,通常是SQL,这是错误中的存储表达式部分。然而,第一个支持.NET反射的数据库还没有发明…@wdosanjos对,测试类有3个属性需要验证,当这些属性等于。。。但这仍然是最重要的same@AbdouTelb对不起,我在中间丢了电话,谢谢…但这仍然是最重要的same@AbdouTelb很抱歉我在中间丢失了TelScript调用。每一个测试都需要一个有效的属性Type Type的更改行。这种情况确实发生了