【问题标题】:Linq to Entities: Where In with 1 value and many columnsLinq to Entities:其中包含 1 个值和许多列
【发布时间】:2019-05-22 20:19:26
【问题描述】:

我知道在 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'));

有没有更简洁的方式来编写这个搜索,或者我有什么最好的方法?

【问题讨论】:

  • 看看这是否适合您...stackoverflow.com/questions/10667675/…
  • 该帖子不涉及实体上的多个字段,因为“流派”只是实体上的一个字段。
  • IN 不是这样工作的。它进行相等比较,而不是 Contains

标签: c# sql linq-to-entities


【解决方案1】:

正如Theodor Zoulias 指出的那样,您没有正确使用 Contains(),因为 SQL 上的 IN 检查相等性,而 SQL 上的 contains 将是 LIKE。你也用 ' 而不是 " 封闭你的字符串 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 查询返回在任何字段上具有该值的任何对象;不指定哪个字段。

可能有更好的方法来做你想做的事情..

【讨论】:

    【解决方案2】:

    你可以的

    .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运行它

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-14
      • 2011-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多