4

I write a LINQ query and for Select clause I created an Expression to reuse it.

My query looks like this

 DataContext.Single.Select(SearchSelector).ToList();

Where as Search Selector defined as

 private Expression<Func<Singles, SearchSingles>> SearchSelector = s =>
    new SearchSingles
    {
    };

The above works fine, but what if I want to use two input parameters? How would I invoke it?

 private Expression<Func<Singles,string, SearchSingles>> SearchSelector = (s,y) =>
    new SearchSingles
    {
    };
Ammar Khan
  • 2,565
  • 6
  • 35
  • 60
  • 1
    Where is the other parameter suppose to come from? Have you tried `Select(s => SearchSelector(s,"Your String Here"))`? – juharr Nov 14 '14 at 19:34
  • Parameter suppose to come come from method which needed to be use inside expression. The above show syntax error – Ammar Khan Nov 14 '14 at 19:38
  • 1
    Maybe `private Func>> SearchSelector = y => s => new SearchSingles{};` and `Select(SearchSelector("Your String Here"))` – juharr Nov 14 '14 at 19:49
  • No luck, seems like I can't invoke like a normal function, it says Delegate, method or event expected – Ammar Khan Nov 14 '14 at 19:53
  • Well I don't work with EF, and I'm out of ideas, I've up voted you so maybe someone else can help you out. – juharr Nov 14 '14 at 19:58
  • @AmmarKhan Juharr's first solution obviously has the problem you mentioned, but his second solution should have no such problem. – Servy Nov 14 '14 at 21:11

2 Answers2

5

Rather than having a field that stores the expression, have a method that creates the expression that you need given a particular string:

private static Expression<Func<Singles, SearchSingles>> CreateSearchSelector(
    string foo)
{
    return s =>
        new SearchSingles
        {
            Foo = foo,
        };
}

You can then use this method like so:

DataContext.Single.Select(CreateSearchSelector("Foo")).ToList();
Servy
  • 202,030
  • 26
  • 332
  • 449
  • However, is it not possible with the way I was trying to do? – Ammar Khan Nov 14 '14 at 21:27
  • What are you trying to do?, specifically? Servy's answer seems to address your question, but maybe your question isn't clear enough. If you want to do it without a named method, you can apply his approach but without the named method. E.g. `DataContext.Single.Select(((Func>>)(y => s => new SearchSingles { Foo = y }))("Foo")).ToList();` It's just like Servy's answer, but with an anonymous method instead, so I'm not really sure if that's the difference you're trying to solve. – Peter Duniho Nov 14 '14 at 21:37
  • @AmmarKhan You can create an expression that actually takes to parameters, sure. You created one in your question just fine. If you're passing it to something that expects an expression with that signature, you don't need to do anything. – Servy Nov 14 '14 at 21:40
  • the 'trick' is that the signature that `Select` is expecting is fixed. Whatever you do must resolve to a delegate of `Func`. So however you go about that... – thewyzard Nov 14 '14 at 21:43
0

what about leaving the signature alone and passing additional parameters as captured values? It might have limited use as an initialized member variable, like this, but if you assign from within some worker function, rather than initialize it during class construction you'd have more power.

private Func<Singles, SearchSingles> SearchSelector = s =>
    new SearchSingles
    {
         someVal = capturedVariable,
         someOther = s.nonCapturedVar
    };

that would work if capturedVariable were a static member

or

private Func<Singles, SearchSingles> SearchSelector = null;
private void WorkerFunction(string capturedVariable, bool capAgain, bool yetAgain)
{
  SearchSelector = s => {
    bool sample = capAgain;
    if (capturedTestVar)
        sample = yetAgain;
    return new SearchSingles
    {
         someVal = capturedVariable,
         someOther = s.nonCapturedVar,
         availability = sample
    };
  };
};

you could have all sorts of fun

*EDIT* references to Expression removed and clarifications

thewyzard
  • 312
  • 1
  • 6
  • statement lambdas cannot be used with expressions. As for your first option, what variable to you expect to close over from that context? – Servy Nov 14 '14 at 21:12
  • yea I glazed over that 'Expression' as I copy/pasted and was just looking into whether it's necessary. In the first, capturedVariable could be a parameter to a worker member function like `private void DoIt(string capturedVariable) { SearchSelector = s=> new SearchSingles { someVal = capturedVariable, someOther = s.nonCapturedVar }; }` – thewyzard Nov 14 '14 at 21:16
  • It could be that, but that's not what you showed in your answer. Had you actually shown that, then you'd have a correct answer. That said you would almost certainly want to have such a method return the expression using that string, not have it assign it to a field. – Servy Nov 14 '14 at 21:17
  • I didn't want to limit imagination. I'll get an edit done after I test the need of the "Expression" – thewyzard Nov 14 '14 at 21:22