4

次の構造の XML ファイルがあります。

<Entities>
    <Request> 
       <ID> A1 </ID> <!-- Can be multiple records with same values -->
       <Finance>
          <StartDate> Some Date </StartDate> <!-- Unique per ID -->
       </Finance>
    <Request>
    <Request> ... </Request>
</Entities>

同じ ID を持つ複数のリクエストが存在する可能性がありますが、そのような場合、StartDate はリクエストごとに異なる必要があります。

ID ごとに最新の 2 つの日付を取り出す必要があります。

これが ID 列と StartDate 列を含む SQL テーブルである場合、正常に機能する次のクエリを使用します。

SELECT ID, StartDate 
FROM ( SELECT ID, StartDate, RANK() 
          OVER (PARTITION BY ID ORDER BY StartDate DESC) rank
       FROM Request ) 
WHERE rank IN ('1','2')

しかし、私は XML 形式のデータを持っています。私が思いついた最善の方法は、ID の StartDate に従ってデータを並べ替えることでした。存在するすべての ID について、最新の 2 つの日付を掘り下げる必要があります。

var cafrequests =

from request in xdoc.Descendants("Request")
orderby (int)request.Element("ID"), 
(DateTime)request.Element("Finance").Element("StartDate") ascending
select new
{
    ID = request.Element("ID"),
    StartDate = request.Element("Finance").Element("StartDate"),
};

Take(2) を使用すると、ID ごとに上位 2 行ではなく、上位 2 行のデータのみが取得されます。

では、上記の LINQ の SQL ステートメントに相当するものを誰か教えてもらえますか? 私は C# でループと条件を使用して XML を解析および管理したくありません。また、LINQ はまったく初めてで (昨日読んで使い始めました)、まだドキュメントを読んでいます。

4

2 に答える 2

2

これは機能します、私はそれをテストしました:

        XDocument doc = XDocument.Load(@"Data.xml");

        var result2 = doc.Element("Entities")
            .Elements("Request")
            .GroupBy(key => key.Element("ID").Value, el => DateTime.Parse(el.Element("Finance").Element("StartDate").Value))
            .Select(el =>
                new
                {
                    id = el.Key,
                    max2 = el.OrderByDescending(date => date).Take(2)
                });
  • doc.Element("Entities")- ドキュメントのルート要素である Entity という名前の要素を取得します。この要素を取得する別の方法は次のとおりです。doc.Root
  • Elements("Request")- Entity の子である Request という名前の要素を取得します
  • GroupBy- SQL のメソッドにやや似てGROUP BYいます。最初のパラメータはグループ化に使用される要素です。これは Request 要素の子です。2 番目のパラメータはDateTimeStartDate 要素 (の子である) から解析する要素セレクター関数です。 Request 要素の子である Finance 要素)
  • .Select(el => new...)- ID と ID の最も高い日付を持つ 2 つのレコードを保持する匿名型を作成するメソッド

同じ結果を得るクエリを次に示しますが、クエリ構文で記述されています (上記の例はメソッド構文です)。

        var result = from el in doc.Root.Elements("Request")
                     group DateTime.Parse(el.Element("Finance").Element("StartDate").Value) by el.Element("ID").Value into grouped
                     select new { 
                         id = grouped.Key,
                         max2 = (from el in grouped
                                 orderby el descending
                                 select el)
                                 .Take(2)
                     };
于 2012-12-19T08:19:57.950 に答える
1

Id でグループ化して最近の日付を選択することはできませんか? このようなもの。結果セット (cafrequests) で ID と対応する日付のリストを取得している場合

var result = cafrequests.GroupBy(x=>x.Id).Select(x=>new{ x.Key,Dates = x.OrderByDescending(y => y.StartDate).Select(y=>y.StartDate).Take(2)}).ToDictionary(x=>x.Key);

これにより、各 ID の上位 2 つの日付が得られます。

于 2012-12-19T08:05:36.217 に答える