2

I have this situation:

if (condition){
   var variable = (from el in ....) //linq to sql query
 }
else{
   var variable = (from el in ....) //linq to sql query
 }

// code where i can`t use the variable

I want to avoid copying code in both conditions.

var getHistoryTips = (from el in objDC.tickets
                      where el.typeOfGame == cANDu[0]
                      && el.username == Membership.GetUser(cANDu[1]).ProviderUserKey.ToString()
                      select new { el.AllGamesTickets, el.WGamesTickets}).FirstOrDefault();


var getHistoryTips = (from el in objDC.tickets
                      where el.typeOfGame == cANDu[0]
                      && el.results != null
                      && el.username == Membership.GetUser(cANDu[1]).ProviderUserKey.ToString()
                      select new { el.AllGamesTickets, el.WGamesTickets}).FirstOrDefault();
5
  • 4
    What does your query look like in both cases? Commented Jul 6, 2011 at 18:16
  • 3
    what do you want to avoid copying? Edit: Now I see your queries. They look identical. If the result of your conditions are the same, why do you even need the conditions? Commented Jul 6, 2011 at 18:16
  • 1
    Need a better idea of what your trying to avoid copying. Commented Jul 6, 2011 at 18:18
  • I want to avoid to put "code" in if and else, only to have query. Commented Jul 6, 2011 at 18:20
  • @0A0D No, in one I have && el.results != null. Commented Jul 6, 2011 at 18:21

4 Answers 4

8

Three options:

Firstly, you can use an "example" - to type the variable:

// Same anonymous type properties and types as later:
var variable = Enumerable.Repeat(0, new { ... });

if (condition) {
    variable = ...;
} else {
    variable = ...;
}

Alternatively, you could use the conditional operator:

var variable = condition ? ... first query ...
                         : ... second query ...

Thirdly, you could build the query up using composition instead. For example, if the only difference is the ordering, you could do:

var firstPart = ...;

var secondPart = condition ? query.OrderBy(...) : query.OrderByDescending(...);

var query = secondPart.Select(...);

EDIT: Now you've given an example, we can make this concrete:

string username = membership.GetUser(cANDu[1]).ProviderUserKey.ToString();
var query = objDC.tickets
                 .Where(el => el.typeOfGame == cANDu[0] &&
                              el.username == username);

if (condition)
{
    query = query.Where(el => el.results != null);
}

var result = query.Select(el => new { el.AllGamesTickets, el.WGamesTickets})
                  .FirstOrDefault();
Sign up to request clarification or add additional context in comments.

6 Comments

See his latest comment: "want to avoid to put "code" in if and else, only to have query"
@0A0D: That's what my third option gives, and I now have a concrete example.
@Jon Skeet Any possibility to do this with two different tables in queries?
@Jon Skeet if I use conditional operator and in one query objDC.tickets, in second other table, then I have problem "no implicit convertion between System.Linq.IQueryable<ticket> and..."
@gormit: I suggest you ask in more detail in a new question.
|
2

You might be able to use the ternary operator:

var variable = (condition) ? (from el in...) : (from el in...);

Where the first linq-to-sql statement (before the colon) is the true case and the linq-to-sql after the colon is the false case. So your code might look like:

var getHistoryTips = (condition) ? (from el in objDC.tickets
                                     where el.typeOfGame == cANDu[0]
                                     && el.username == Membership.GetUser(cANDu[1]).ProviderUserKey.ToString()
                                     select new { el.AllGamesTickets, el.WGamesTickets}).FirstOrDefault() : 
                                   (from el in objDC.tickets
                                     where el.typeOfGame == cANDu[0]
                                     && el.results != null
                                     && el.username == Membership.GetUser(cANDu[1]).ProviderUserKey.ToString()
                                     select new { el.AllGamesTickets, el.WGamesTickets}).FirstOrDefault();

1 Comment

I think he wants to prevent typing it twice (e.g. concatenate queries adding in the extra conditional of el.results != null)
1

Use your condition in the query itself in the where clause.

You may have to write something like,

var variable = (from el in .... where (condition && trueBlockCondition) || (!condition && falseBlockCondition) 

Comments

1

Functionality you are asking for can be implemented using extensions method, instead of LINQ syntax.

Here are the example:

var source = objDC.tickets.Where(el => 
    el.typeOfGame == cANDu[0]
    && el.username == Membership.GetUser(cANDu[1]).ProviderUserKey.ToString());

if(condition)
    source = source.Where(el => el.results != null);

var getHistoryTips = source
    .Select(el => new { el.AllGamesTickets, el.WGamesTickets}))
    .FirstOrDefault();

If query getting complicated, as an option, selector can be implemented via Expression feature.

Expression<Func<ObjDCType, ShallowObjDCType>> selector = 
   (el) => new ShallowObjDC{ el.AllGamesTickets, el.WGamesTickets});

var getHistoryTips = source.Select(selector).FirstOrDefault();

This technique will allow you yo pass selector inside other function, in case things are getting more complex, however it requires you to define additional class or use dynamic, instead of anonymous classes.

Note, that you can't use Func without Expression, since this will cause ORM (LINQ/EF) to pull all object from database.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.