2

複数の物件で検索条件を実行したいのですが、問題があります。検索条件の一部ではない空または null のプロパティがある場合は、助けてください。以下のコードは次のとおりです。

public List<AccountDto> getSearchedAccount(int accountid,int userid,String holdername,String type,double balance,String status)
{
    List<AccountDto> results = new List<AccountDto>();
    for (int i = 0; i < list.Count; i++)
    {
        AccountDto dto = (AccountDto)list[i];
        if ((dto.Accountid == accountid) && (dto.Userid==userid) && (dto.Holdername.Equals(holdername)) && (dto.Balance == balance) && (dto.Status.Equals(status)) )
        {
            results.Add(dto);
        }

    }

    return results;
}

検索条件に含まれないフィールドが null または空である場合の正しい if ステートメントを教えてください。

4

6 に答える 6

4

次のようになります。

 if (accountid < 0 || dto.Accountid == accountid) 
     && ... 
     && (string.IsNullOrEmpty(holdername) || dto.Holdername.Equals(holdername)) 
     && ... )
    {
        results.Add(dto);
    }

値が設定されていない場合、または比較が重要な場合に真となる各条件の or を導入します。たとえば、holdername が null または空の場合、Equals of Holdername は評価されません。

于 2013-03-08T15:21:33.237 に答える
3

そのためのメソッドを作ってみませんか?そのメソッドでは、プロパティがnull空か、それ以外かを確認できます。

private bool CheckAccount(AccountDto dto, int accountid, int userid, String holdername, string type, double balance, String status){
 bool isTrue = true;
 ...
 if(holdername != null){
    if(!dto.Holdername.Equals(holdername))
          return false;
 }
 ...
 return true; //all properties are true
}
于 2013-03-08T15:22:23.510 に答える
0
/*** Answer with the comments in code ***/ 
// don't create a class to represent your criteria
// Dictionary is enough for use and supported by Linq
// don't use a lot of `&&` or `if`; one `if` is enough
// all the rules is in deferred execution, only executes when it really needs 
// evaluated and the order to put where clauses matters, don't make it changed
// it performs like short-circuit evaluation

/// <summary>
/// declared as partial for easily coexists with original code
/// if not used(e.g already declared) then not paste to file
/// </summary>
partial class AccountDto /* known members */ {
    public int Accountid;
    public int Userid;
    public String Holdername;
    public int Balance;
    public String Status;
}

/// <summary>
/// declared as partial for easily coexists with original code
/// if getSearchedAccount is declared with another class name
/// then just rename the partial class to that name and remove 
/// all `static`(if that class is non-static) 
/// the class initializer, then become constructor; remember to 
/// match the name of class and constructor
/// </summary>
partial class AccountDto {
    /// <summary>
    /// declare as static for this demo; 
    /// not necessarily be static if it's declared in another 
    /// class where list is declared
    /// </summary>
    public static List<AccountDto> getSearchedAccount(
        int accountid, int userid,
        String holdername, String type,
        double balance,
        String status
        ) {
        var results=new List<AccountDto>();

        // make a copy of IgnoreRules and clear; equivalent to 
        // var matchRules=new Dictionary<String, Func<AccountDto, bool>>();
        // IgnoreRules is not changed with these two statement
        // just prevent to see too many angle braces
        var matchRules=IgnoreRules.ToDictionary(x => x.Key, x => x.Value);
        matchRules.Clear();

        // the parameters only known in this method thus can only added here
        matchRules.Add("accountid", x => accountid==x.Accountid);
        matchRules.Add("userid", x => userid==x.Userid);
        matchRules.Add("holdername", x => holdername==x.Holdername);
        matchRules.Add("balance", x => balance==x.Balance);
        matchRules.Add("status", x => status==x.Status);

        for(int i=0; i<list.Count; i++) {
            var dto=(AccountDto)list[i];

            if((from ignoreRule in IgnoreRules
                from matchRule in matchRules
                where ignoreRule.Key==matchRule.Key
                where !ignoreRule.Value(dto)
                select matchRule.Value(dto)).All(x => x))
                results.Add(dto);
        }

        return results;
    }

    /// <summary>
    /// criteria for `don't test for matching`
    /// </summary>
    public static Dictionary<String, Func<AccountDto, bool>> IgnoreRules {
        get;
        set;
    }

    /// <summary>
    /// use class initializer to add common IgnoreRules
    /// </summary>
    static AccountDto() {
        IgnoreRules=new Dictionary<String, Func<AccountDto, bool>>();
        IgnoreRules.Add("accountid", x => 0==x.Accountid);
        IgnoreRules.Add("userid", x => 0==x.Userid);
        IgnoreRules.Add("holdername", x => String.IsNullOrEmpty(x.Holdername));
        IgnoreRules.Add("balance", x => 0==x.Balance);
        IgnoreRules.Add("status", x => String.IsNullOrEmpty(x.Status));
    }

    /// <summary>
    /// declare as static for this demo; 
    /// not necessarily be static if it's declared in another 
    /// class where getSearchedAccount is declared
    /// </summary>
    public static List<AccountDto> list=new List<AccountDto>();
}
于 2013-03-08T17:10:39.830 に答える
0

おそらくdefault(type)string.IsNullOrEmpty(...)に対してチェックします

したがって、次のようになります。

public List<AccountDto> getSearchedAccount(int accountid, int userid, string holdername, string type, double balance, string status)
{
    var results = new List<AccountDto>();

    for (int i = 0; i < list.Count; i++)
    {
        AccountDto dto = (AccountDto)list[i];

        if (accountid != default(int) && accountid != dto.Accountid)
            continue;
        if (userid != default(int) && userid != dto.Userid)
            continue;
        if (!string.IsNullOrEmpty(holdername) && !holdername.Equals(dto.Holdername))
            continue;
        if (!string.IsNullOrEmpty(type) && !type.Equals(dto.Type))
            continue;
        if (balance != default(double) && balance != dto.Balance)
            continue;
        if (!string.IsNullOrEmpty(status) && !status.Equals(dto.Status))
            continue;

        results.Add(dto);
    }

    return results;
}

または式ツリーを利用する

public List<AccountDto> getSearchedAccount(int accountid, int userid, string holdername, string type, double balance, string status)
{
    IQueryable<AccountDto> query = list.AsQueryable();

    if (accountid != default(int))
        query = query.Where(i => i.Accountid.Equals(accountid));
    if (userid != default(int))
        query = query.Where(i => i.Userid.Equals(userid));
    if (!string.IsNullOrEmpty(holdername))
        query = query.Where(i => i.Holdername.Equals(holdername));
    if (!string.IsNullOrEmpty(holdername))
        query = query.Where(i => i.Type.Equals(type));
    if (balance != default(double))
        query = query.Where(i => i.Balance.Equals(balance));
    if (!string.IsNullOrEmpty(holdername))
        query = query.Where(i => i.Status.Equals(status));

    return query.Select(i => i).ToList<AccountDto>();
}

いくつかの考え

  • 2倍ではなく、金額に10進数を使用するつもりだったと思います。
  • 新しいフィールドを追加するたびにメソッド シグネチャを変更する必要がないように、基準を表すオブジェクトを作成します。

    public List getSearchedAccount(AccountSearchCritera criteria) { ... }

于 2013-03-08T15:46:09.813 に答える
0

検索基準で集約フィルターを作成できます。以下の投稿には、あなたが探しているものと同じものがあると思います。これを試して

于 2013-03-08T15:30:55.693 に答える
0

これはあなたが探しているものかもしれないと思います: C# Coalesce

于 2013-03-08T15:22:32.607 に答える