inquisitive_one
inquisitive_one

Reputation: 1495

LINQ query with addition to WHERE clause

I want to run the following LINQ query twice but with an addition to the Where clause:

var TickList = 
    (from comp in Companies
    join eqRes in Equity_issues on comp.Ticker equals eqRes.Ticker
    where !comp.Coverage_status.Contains("dropp") 
        && !comp.Coverage_status.Contains("Repla") && eqRes.Primary_equity.Equals('N')
     select new 
    {
        LocalTick = eqRes.Local_ticker.Trim(),
        Exchange = eqRes.Exchange_code.Contains("HKSE") ? "HK" : (eqRes.Exchange_code.Contains("NSDQ") ? "NASDQ" : eqRes.Exchange_code),
        Ticker = comp.Ticker.Trim()
    }).ToList();

This query works fine, but I need to pass an additional parameter to the Where clause:

where !comp.Coverage_status.Contains("dropp") 
        && !comp.Coverage_status.Contains("Repla") && eqRes.Primary_equity.Equals('N')
        && !comp.Coverage_status.Contains("Intl")  <--- new addition

Is there a way to do this without being DRY? Isn't there an efficient way of doing this without repeating the query with the new addition?

Upvotes: 0

Views: 173

Answers (3)

WhiteleyJ
WhiteleyJ

Reputation: 1691

Probably overkill here but there have been situations where I've created a full blown query object that internally held an IQueryable and used methods on the object to add the where clause (mostly for letting users filter and sort their results)

public class TickList{
    IQueryable<Foo> _query;
    public TickList(){
        _query = from comp in Companies
                 join eqRes in Equity_issues on comp.Ticker equals eqRes.Ticker
                 select new Foo {
                     LocalTick = eqRes.Local_ticker.Trim(),
                     Exchange = eqRes.Exchange_code.Contains("HKSE") ? "HK" :(eqRes.Exchange_code.Contains("NSDQ") ? "NASDQ" : eqRes.Exchange_code),
                     Ticker = comp.Ticker.Trim()
                 };
    }
    public void WhereCoverageContains(string text){
        _query = _query.Where(x => x.Coverage_Status.Contains(text));
    }
    public void WherePrimaryEquityIs(string text){
        _query = _query.Where(x => x.PrimaryEquity.Equals(text));
    }
    public List<Foo> ToList(){
        return _query.ToList();
    }
}

It's super verbose so use with caution. Sometimes it's possible to be too dry.

Upvotes: 0

Riad Baghbanli
Riad Baghbanli

Reputation: 3319

See the code below if you want to be DRY:

var keywords = new string[] { "dropp", "Repla", "Intl" };

var TickList = Companies
    .Join(Equity_issues, c => c.Ticker, e => e.Ticker, (c, e) => new { c, e })
    .Where(ce => ce.e.Primary_equity.Equals('N')
                 && keywords.All(v => !ce.c.Coverage_status.Contains(v)))
    .Select(ce => new 
     {
        LocalTick = ce.e.Local_ticker.Trim(),
        Exchange = ce.e.Exchange_code.Contains("HKSE")
                   ? "HK"
                   : (ce.e.Exchange_code.Contains("NSDQ")
                     ? "NASDQ"
                     : ce.e.Exchange_code),
        Ticker = ce.c.Ticker.Trim()
     })
    .ToList();

Now you can run this query with any combination of keywords.

Upvotes: 0

ASh
ASh

Reputation: 35646

// select additional Intl field (similar to Exchange)
var TickList = 
    (from comp in Companies
    join eqRes in Equity_issues on comp.Ticker equals eqRes.Ticker
    where !comp.Coverage_status.Contains("dropp") 
        && !comp.Coverage_status.Contains("Repla") && eqRes.Primary_equity.Equals('N')
     select new 
    {
        LocalTick = eqRes.Local_ticker.Trim(),
        Exchange = eqRes.Exchange_code.Contains("HKSE") ? "HK" : (eqRes.Exchange_code.Contains("NSDQ") ? "NASDQ" : eqRes.Exchange_code),
        Intl = comp.Coverage_status.Contains("Intl") ? 1 : 0,
        Ticker = comp.Ticker.Trim()
    }).ToList();

// use LINQ to objects to filter results of the 1st query
var intl = TickList.Where(x => x.Intl = 0).ToList();

Upvotes: 1

Related Questions