Linq to Entities: Where In с 1 значением и множеством столбцов - PullRequest
2 голосов
/ 22 мая 2019

Я знаю, что в 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 голосов
/ 23 мая 2019

Вы не используете Contains () должным образом, как указано Theodor Zoulias , потому что IN в SQL проверяет равенство, в то время как contains будет LIKE в SQL. также вы заключаете в себя строку val с ' вместо ", ' работает только для одного символа.

Предполагая, что вы пытаетесь получить «m», если любое свойство имеет определенное значение, вам придется использовать отражение :

Сначала создайте метод для цикла по объекту и сопоставления с требуемым значением

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, поскольку он извлекает каждое (публичное) свойство.

Теперь просто используйте ваш новый метод bool на вашем linq: (не очень хорошая идея относительно производительности в зависимости от контекста)

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

Хотя все это возможно, у вас, вероятно, есть проблема архитектуры , потому что вы очень быстро потеряете ссылку, поскольку этот запрос linq возвращает любой объект, имеющий это значение в любом поле; без указания какого поля.

Возможно, есть лучшие способы сделать то, что вы пытаетесь сделать.

0 голосов
/ 23 мая 2019

Вы можете сделать

.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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...