Linq to Entities:其中In具有1值和许多列

时间:2019-05-22 20:19:26

标签: c# sql linq-to-entities

我知道在sql中您会执行类似的操作

WHERE 'val' IN (field1, field2, field3, field4, ...)

我想知道是否可以使用Linq对实体执行类似的操作?我现在唯一能想到的就是像下面这样在要搜索的字段上创建一个巨大的“或”语句

.where(m => 
    m.field1.Contains('val') ||
    m.field2.Contains('val') ||
    m.field3.Contains('val') ||
    m.field4.Contains('val'));

有没有一种更干净的方式来编写此搜索,或者我所获得的一切都很好?

2 个答案:

答案 0 :(得分:0)

你可以

.Where(f => new string[] { f.field1, f.field2, f.field3 }.Any(s => s.Contains("val")));

具有您发布的代码的行为,或者

.Where(f => new string[] { f.field1, f.field2, f.field3 }.Contains("val"));

检查是否相等。

但是我不能说这是一个关于性能的好主意。

下面是代码示例:

public class ClassWithFields
{
    public int Id { get; set; }
    public string Field1 { get; set; }
    public string Field2 { get; set; }
    public string Field3 {get;set;}
}


public class Program
{
    public static void Main()
    {
        var listFields = new List<ClassWithFields>()
        {
                new ClassWithFields { Id = 1, Field1 = "val", Field2 = "qewr", Field3 = "asdqw" },
                new ClassWithFields { Id = 2, Field1 = "asdf", Field2 = "asdd", Field3 = "asdqw" },
                new ClassWithFields { Id = 3, Field1 = "asdf", Field2 = "qewr", Field3 = "qwvaleqwe" }
        };

        var containsVal = listFields.Where(f => new string[] { f.Field1, f.Field2, f.Field3 }.Any(s => s.Contains("val")));
        var equalsVal = listFields.Where(f => new string[] { f.Field1, f.Field2, f.Field3 }.Contains("val"));
    }
}

您可以在https://dotnetfiddle.net/lXSoB4

上运行它

答案 1 :(得分:0)

您没有正确使用Theodor Zoulias所指出的Contains(),因为SQL上的IN会检查相等性,而SQL上的contains会像是。此外,您还用'而不是来封装字符串val,'仅适用于单个字符。

假设您尝试检索任何属性具有特定值的“ m”,则必须使用 reflection

首先创建一种方法来遍历对象并匹配所需的值

public bool FieldSearch(object a, string b)
{
  //Get the type of your object, to loop through its properties
  Type t = a.GetType();
  //loop and check (the loop stops once the first property that matches has been found!)
  foreach(PropertyInfo p in t.GetProperties())
  {
    if(p.GetValue(a).ToString()==b)
    {
    return true;
    }
  }
  return false;
}

在使用 GetProperties()时要小心,您可能要添加BidingAttributes,因为它会检索每个(公共)属性。

现在只需在linq上使用新的bool方法:(根据上下文,这不是关于性能的好主意)

.where(m => FieldSearch(m,"val"))

尽管所有这一切都是可能的,但是您可能会遇到体系结构问题,因为您将很快失去引用,因为此linq查询会返回任何在任何字段上具有该值的对象。而不指定哪个字段。

可能有更好的方法来做您想做的事情。