Reputation: 1495
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
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
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
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