Вопрос по c#, linq-to-sql, linq, linq-to-objects – Использовать строку в качестве имени поля в LINQ

9

Посмотрите код ниже. Я хотел бы заменитьUSERNAME по имени поля полученному в параметреfield, Этот метод должен иметь возможность выполнять поиск по нескольким полям.

Поблагодарить,

public void Searching(string field, string stringToSearch)
{
    var res = 
        from user in _dataContext.USERs where 
        user.USERNAME.Contains(stringToSearch)
        select new 
        {
          Id = user.ID,
          Username = user.USERNAME
        };

}
Это LINQ для SQL или LINQ для объектов? TDaver
Я использую LINQ to SQL Kris-I

Ваш Ответ

3   ответа
15

Вам нужно забыть об анонимном типе, возможно используйтеTuple<int,string> вместо; но: как насчет:

IQueryable<Foo> source = // YOUR SOURCE HERE
      // in-memory dummy example:
      // source = new[] {
      //    new Foo {Id = 1, Bar = "abc"},
      //    new Foo {Id = 2, Bar = "def"}
      // }.AsQueryable();

string field = "Bar";
string stringToSearch = "d";
var param = Expression.Parameter(typeof (Foo), "x");
var predicate = Expression.Lambda<Func<Foo, bool>>(
    Expression.Call(
        Expression.PropertyOrField(param, field),
        "Contains", null, Expression.Constant(stringToSearch)
    ), param);
var projection = Expression.Lambda<Func<Foo, Tuple<int, string>>>(
    Expression.Call(typeof(Tuple), "Create", new[] {typeof(int), typeof(string)},
        Expression.PropertyOrField(param, "Id"),
        Expression.PropertyOrField(param, field)), param);
Tuple<int,string>[] data = source.Where(predicate).Select(projection).ToArray();
Крис говоритThis methode must be able to make some search several field. Если я не ошибаюсь, он хочет отправить параметр, который будет именем столбца в запросе. Например, USERNAME, CELLPHONE, ADDRESS. То, что я спрашиваю, не должно ли это быть сделано с тремя различными запросами, но не с помощью метода, подобного этому? Прости меня, если я неправильно понял.
Так что это возможно, но это хорошая практика для запроса различных столбцов? Разве мы не должны делить их, мистер Гравелл? И я действительно восхищаюсь вашей работой.
прекрасный прекрасный прекрасный B-)
Черт, ты был быстрее на минуту ... а у меня не было времени проверить мои. Надеюсь, это все еще работает, хотя :)
@RoboLover, что значит «разделить их»? ? Как основной "найди мне пару совпадений"; Я хочу уникальный идентификатор и сопоставляемую вещь & quot; это не является необоснованным
4

На самом деле это возможно с помощью Expression API:

public void Searching(Expression<Func<User,string>> field, string stringToSearch)
{

   var call = Expression.Call(field.Body, typeof (string).GetMethod("Contains"), new[] {Expression.Constant(value)});
   Expression<Func<User, bool>> exp = Expression.Lambda<Func<User, bool>>(Expression.Equal(call, Expression.Constant(true)), field.Parameters);


    var res =  _dataContext.USERs.Where(exp).Select(u=>new { id= u.ID, Username = u.USERNAME});

}
У меня много ошибок: field.Body? Kris-I
Проекция (Select) also должно быть пользовательское выражение
О, я не понял эту часть требования :(
@MarcGravell: почему? это полностью напечатано полностью!
"Я хотел бы заменить"USERNAME по имени поля получите в параметреfield& Quot; - следовательноu.USERNAME does not exist; это было быu.SomethingElseHere, Мне нравится ваше использование входящего выражения для base-body и параметра!
3

То, что вы пытаетесь, невозможно. Однако вы можете использоватьдинамическая библиотека linq добиться того, что вы хотите

Пример ожидания @MarcGravell, другие образцы не работают, ошибки компиляции и другие Kris-I
если мы уберем анонимный тип (возможно, вместо него используйте кортеж),is возможный; действительно, если динамическая библиотека LINQ может это сделать, это ДОЛЖНО быть возможным; работает на примере ...

Похожие вопросы