2012-06-05 2 views
0

У меня есть лямбда о том, что есть отображение, как это:Если оператор и задания в лямбда-выражения

public enum Status 
{ 
    Completed, 
    InComplete, 
    Ok 
} 

Запрос:

var courses = query.Select(c => new SomeModel 
     { 
      Status = c.someQuery() ? Status.Completed : Status.Ok 
     }); 

Так что я хочу Статус, чтобы иметь несколько, если заявления и не только тройная операция. Напр.

var courses = query.Select(c => new SomeModel 
     { 
      Status = if(c.someQuery()) 
        { 
         return Status.Completed; 
        } 
        else if(c.someOtherQuery()) 
        { 
         return Status.InComplete; 
        } 
        else if(c.someOtherQuery1()) 
        { 
         return Status.Ok; 
        } 
     }); 

Так как же я могу добиться чего-то подобного? Я использую ORM Framework.

+2

Очень важно различать, используете ли вы ORM, такие как L2S или Entity Framework, который переводит ваши лямбды в SQL (в этом случае ваши параметры сильно ограничены), или это просто обычная лямбда. Другими словами, каков тип 'query'? –

+0

@KirkWoll-запрос может работать в контексте, 'someQuery' может быть объединен, wheres, any и т. Д. Вместе. –

+0

Если запрос L2S или EF, вам может потребоваться перечислить исходный запрос (например, вызвать '.ToList()'), прежде чем запускать для него тройное утверждение. –

ответ

5

Вы можете вкладывать ваши тройные операции:

Status = c.someQuery() ? Status.Completed : 
    c.someOtherQuery() ? Status.InComplete : Status.Ok 
+1

это возможно, но это не обязательно хорошая идея. ИМХО его немного кода запах –

+2

@ Джейсон, нет ничего плохого в этом. Термин «запах кода» делает меня вредным, и я думаю, что это ленивый способ сказать: «Я не знаю, что не так с этим кодом, но я собираюсь предположить, что в этом что-то не так, потому что моя кишка говорит так. " –

+2

С круглыми скобками, чтобы было ясно, какой из них идет первым, я не думаю, что это слишком много запаха кода. –

2

Не могли бы вы, возможно, сделать это, как это?

myObjects 
     .Where(d => d.isTrue == true && d.Value == 77) 
     .Update(e => { e.Value = 1; e.isTrue = false; }); 

Использовать LINQ тщательно, она может взорваться в любой момент ;-)

/// <summary> 
    /// Used to modify properties of an object returned from a LINQ query 
    /// </summary> 
    /// <typeparam name="TSource">The type of the source.</typeparam> 
    /// <param name="input">The source</param> 
    /// <param name="updater">The action to perform.</param> 
    public static TSource Update<TSource>(this TSource input, Action<TSource> updater) 
    { 
     if (!updater.IsNull() && !input.IsNull()) 
     { 
      updater(input); 
     } 
     return input; 
    } 

Чтобы полностью объяснить это:

public DataRow DoSomething(DataRow dataRow) 
    { 
     //DoSomething 
     return dataRow; 
    } 

    var query = from dataRow in myDataTable.Rows.Cast<DataRow>() 
       where 
        Double.TryParse(dataRow["Distance"].ToString(), out distance) 
        && distance > (11) && distance <= 99 
       select dataRow.Update(f => DoSomething(f)); 

Таким образом, вы можете запустить метод (someOtherQuery) и верните перечисление в LINQ, без гнездования (которое является baaaaaaad ... IMHO).

+3

Моя голова только что взорвалась: 'e.true = false' – ivowiblo

+0

hahahahaha, я просто вырвал код, который был реальным, поскольку я не люблю помещать свои реальные структуры данных в сеть. Никогда не знаешь, кто смотрит;) - Кроме того, голосуйте за то, что я буквально LOL! – Faraday

1

Поскольку эта логика не может быть переведена в инструкцию T-SQL, вам нужно сделать это в памяти. Что я хотел бы сделать это, чтобы добавить эту логику к модели:

var courses = query.ToList().Select(c => new SomeModel 
    { 
     Status = c.GetStatus(); 
    }); 

public class SomeModel  
{ 
    ... 

    public Status GetStatus() 
    { 
     if(this.someQuery()) 
     { 
      return Status.Completed; 
     } 
     else if(this.someOtherQuery()) 
     { 
      return Status.InComplete; 
     } 
     else if(this.someOtherQuery1()) 
     { 
      return Status.Ok; 
     } 
     ... 
    } 
} 

Обратите внимание, что вызов ToList() выполнит запрос с использованием EntityFramework и Select будет выполняться по списку объектов.

Смежные вопросы