开发者

Linq Contains to return ALL items or selected ones?

Is it possible to write a linq select with a where 开发者_如何学Goclause which can select either ALL items or specific ones? In SQL I could use "where currency like '%'" to return everything. I am trying to write a method so I can pass in the currency (amongst a few other things) and re-use the same method.

e.g.

Just GBP

from a in accounts
where currency.Contains('GBP')
select a

Just GBP

from a in accounts
where currency == 'GBP'
select a

ALL currencies?

from a in accounts
where currency like '%'
select a


Have you tried to "store" the query and filter it in a later step, like so:

IEnumerable<AccountClass> GetAccounts(string filter = null)
{
    var query = from a in accounts select a;
    if (!string.IsNullOrEmpty(filter))
    {
        query = query.Where(a => a.Currency.Contains(filter));
    }
    return query;
}

This could be collapsed in a single query, but seems less readable to me and may not work with LINQ-to-SQL (or other LINQ-to-DB where the expression is translated to a query):

from a in accounts
where string.IsNullOrEmpty(filter) || a.Currency.Contains(filter)
select a


You could try

.Where(c => currencyToFind == null ? true : c==currencyToFind)

And pass in a null for the currency you want if you want them all.

In a linq query expression:

from a in accounts
where (currencyToFind == null ? true : account.Currency==currencyToFind)
select a


If you want to return all currencies, just don't use any where (both in LINQ and SQL):

from a in accounts
select a

Or, if you really don't need to do anything else, just use accounts.

EDIT: If you want to have one method, and, say, any currency is represented by null, you could do it like this:

IQueryable<Account> result = accounts;

if (currency != null)
    result = result.Where(a => a.Currency == currency);

return result;


It's hard to answer this without more information, but here's the sort of pattern that you appear to want (this would be overengineering in my book unless really warranted):

public static Expression<Func<Account, bool>> GetAccountCurrencyPredicate
   (this FilterKind filter, string value)
{
    switch (filter)
    {
        case FilterKind.Exact:
            return account => account.Currency == value;

        case FilterKind.Contains:
            return account => account.Currency.Contains(value);

        case FilterKind.All:
            return account => true;

        default:
            throw new ArgumentException("Unknown FilterKind.", "filter");
    }
}

And then use it as:

FilterKind filter = ...
string value = ...
IQueryable<Account> accounts = ...

var predicate = filter.GetAccountCurrencyPredicate(value);
var matchingAccounts = accounts.Where(predicate); 


Can't you just filter on a condition?

var selectedAccounts = accounts.Select(y => y);
if(!string.IsNullOrEmpty(currency))
{
     selectedAccounts = selectedAccounts.Where(y => y.Currency.Contains(currency));
}

You could even try an even more generic version:

IEnumerable<Account> GetAccounts(Func<Account, bool> filter)
{
    var selectedAccounts = accounts.Select(y => y);
    if(filter != null)
    {
        selectedAccounts = selectedAccounts.Where(filter);
    }
    return selectedAccounts;
}

IEnumerable<Account> GetAccountsForCurrency(string currency)
{
    if(string.IsNullOrEmpty(currency))
    {
         return GetAccounts(null);
    }
    return GetAccounts((y) => y.Currency.Contains(currency));
}

Now you have one more specific and one more general method that could be used for different types of filtering.


Why are you using a where statement if you want to return anything? where is made for filtering, so if you want to return anything you can either try

from a in accounts
select a

or, if you want to have a where statement in it

from a in accounts
where 1 = 1
select a

or, if you want a like statement i suggest using a regex

from a in accounts
let r = new Regex("expression")
where r.IsMatch(a.currency)
select a;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜