3

やらなければならない悪い要件があります。とにかく、それをアプリケーションに実装する必要があります。

Trackクラスがあります

public class Track
{
    public string Name { get; set; }
    public string City { get; set; }
    public string Country { get; set; }
}

そして、私はいくつかのテストデータを持っています

List<Track> Records = new List<Track>
{ 
    new Track { City = "a", Name = "a",  Country = "i" }, // Track 1
    new Track { City = "b", Name = "b",  Country = "i" }, // Track 2
    new Track { City = "a", Name = null, Country = "J" }, // Track 3
    new Track { City = "c", Name = "a",  Country = "J" }, // Track 4
    new Track { City = "b", Name = "a",  Country = null}, // Track 5
};

Records要件は、渡された値に基づいてデータをクエリする必要があることです。いずれかのプロパティが である場合null、検索条件はそのプロパティを無視する必要があります。プロパティに基づいてクエリする必要がありますNonNull

If i query for City = a, Name = "b", Country = "i" then Result is: Track 1 & Track 3
If i query for City = c, Name = "p", Country = "w" then Result is: Track 4

Name&Countryには null 値がありますTrack 3Track 5そのため、検索では無視されます。それが明確であることを願っています

私は最終的に以下のロジックにたどり着きました

var filterRecords = new List<Track>();
if (!Records.Any(t => string.IsNullOrWhiteSpace(t.City)))
{
    filterRecords = Records.Where(c => c.City == _city).ToList();  // Here _city is the method parameter.. assume "a"
}

if (!Records.Any(t => string.IsNullOrWhiteSpace(t.Country)))
{
    filterRecords = filterRecords.Where(c => c.City == _country).ToList();  // Here _country is the method parameter.. assume "c"
}

Trackクラスには 12 個のプロパティがあります。上記のような 12 回のチェックは良い兆候ではありません。LINQまたはその他の簡単なものを使用してこれを達成したいと思います。

何か提案をお願いします?.

4

5 に答える 5

6

私の頭に浮かんだ最善の解決策は、集計フィルターを作成することです (コレクションをフィルター処理するためのすべての可能なプロパティが既にあり、それらは null 可能であるため、そのために Track オブジェクトを使用できます):

Track filter = records.Aggregate(
    new Track() { City = _city, Country = _country, Name = _name },
    (f, t) => new Track()
    {
        City = String.IsNullOrEmpty(t.City) ? null : f.City, 
        Country = String.IsNullOrEmpty(t.Country) ? null : f.Country,
        Name = String.IsNullOrEmpty(t.Name) ? null : f.Name
    },
    f => f);

これにより、null を持つフィールドを定義するためにコレクションを 1 回繰り返すだけで済みます。次に、レコードにフィルターを適用するだけです。

var query = from t in Records
            where (filter.City == null || t.City == filter.City) &&
                    (filter.Country == null || t.Country == filter.Country) &&
                    (filter.Name == null || t.Name == filter.Name)
            select t;
于 2012-11-08T17:06:48.647 に答える
0

返される結果の質と量は重要ですか? 数量を処理するメカニズムがあると思います。

クエリをスローする前に、検索キーワードを検証できます。null だけを気にしますか? 冗長なキーワードはどうですか?1. キーワードの検証 - 12 個をループできます。2. 強力な検索キーワードを作成する 3. クエリを実行する

ここで説明した以上のことがなければ、かなり簡単に思えます。

あなたの質問に対する私の理解が期待された方向にない場合は、私を修正してください。

于 2012-11-08T16:56:51.013 に答える
0

これらの式を簡単に連結して、次のようなものを作成できます。レコードを X 回列挙すると、コードが遅くなります。例:

var actualResult = Records
       .Where(x => x.City == _city || string.IsNullOrEmpty(x.City))
       .Where(x => x.Country == _country || string.IsNullOrEmpty(x.Country))
       /// .... and so on
       .ToList()

12 行のコードを書くだけでなく、リフレクションとマッピングを含むより複雑なソリューションもありますが、この状況では必要ありません。資産数が膨大な場合は、それだけの価値があるかもしれません。しかし、12 個のプロパティは十分に小さいため、コードの匂いはあまり感じられません。

于 2012-11-08T16:46:28.500 に答える
0

私が理解しているなら、それはこの簡単なはずです:

var results = Records.Select(p => p.City != null && 
              p.Country != null && 
              p.Name != null).ToList();
于 2012-11-08T16:53:23.157 に答える
-1

このようなもの

var listRecords = from track in Records
where (track.city == _city && !string.IsEmpyOrNull(track.city)) && 
(track.Name== _name && !string.IsEmpyOrNull(track.Name))
select track;

残りの条件を追加できます

于 2012-11-08T16:48:58.570 に答える