2

アラートの時系列リストを返す必要があります。以下の方法1はこれを行います。

また、AlertTypeID = {1,2,3,6,8,9、x}の場合、CreateDateごとにアラートを返し、月ごとに並べ替えるように、特定のアラートタイプのアラートを取得する必要があります。以下の方法2はこれを行います。

ここで、メソッド2の結果をメソッド1の結果に挿入する必要があります。メソッド2によって返されるアイテムは月ごとに整理されていますが、最新のもののみを考慮しています。メソッド2の最新のサブグループアイテムのみが、メソッド1から返されたアイテムの時系列順に従う必要があります。このサブグループアイテムは、サブグループ2の残りの月次アイテムが配置される場所を決定します。

最後の要件は、重複を削除する必要があることです。サブグループアラートからアイテムが返される場合、そのアイテムはプライマリグループアラートにも存在できません。

以下に、私が達成しようとしている効果の図を示します。

december alert 1 (12/23/2012)
december alert 2 (12/21/2012)
december alert 3 (12/20/2012)
december subalert 1 (12/19/2012)
december subalert 2 (12/18/2012)
december subalert 3 (12/04/2012)
december subalert 4 (12/01/2012)
december alert 4 (12/18/2012)
december alert 5 (12/12/2012)
november alert 1 (11/22/2012)
november alert 2 (11/16/2012)
november subalert 1 (11/14/2012)
november subalert 2 (11/08/2012)
november alert 3 (11/12/2012)

コード:

  1. 日時別のすべてのアラート

    List<Alert> result = new List<Alert>();
    using(NeuroLabLinqDataContext dc = conn.GetContext())
    {
        IEnumerable<Alert> alerts = (from a in dc.Alerts
                                     where a.AccountID == AccountID
                                     orderby a.CreateDate descending
                                     select a).Take(40);
        result = alerts.ToList();
    }
    return result;
    
  2. 月別のアラートタイプ

    List<Alert> result = new List<Alert>();
    int[] alertTypes = {1,2,3,4,5,6,7,8,9};
    
    using (NeuroLabLinqDataContext dc = conn.GetContext())
    {
        IEnumerable<Alert> alerts = (from a in dc.Alerts
                                     where a.AccountID == AccountID &&
                                     alertTypes.Contains(a.AlertTypeID)
                                     orderby ((DateTime)a.CreateDate).Month ascending
                                     select a).ToList();
    }
    
    return result;
    

最後のselectステートメントのグループ化は次のようになります。

 select new { Date = alerts.CreateDate, 
              Message = alerts.Message, 
              Type = alert.AlertTypeID, 
              RecentActivity = [if from method 2, then true] };

更新:更新されたメソッド

 public List<Alert> GetAlertsByAccountID(Int32 AccountID, params int[] alertTypes)
        {

            List<Alert> result = new List<Alert>();

            using (NeuroLabLinqDataContext dc = conn.GetContext())
            {
                var all = (from a in dc.Alerts
                           where a.AccountID == AccountID
                           orderby a.CreateDate descending
                           select a);

                int abc = all.Count();

                var first = all
                    .Where(a => a.AccountID == AccountID) && !alertTypes.Contains(a.AlertTypeID))
                    .OrderByDescending(a => a.CreateDate)
                    .GroupBy(a => a.CreateDate.Date)
                    .ToDictionary(g => g.Key);

                var firstKeys = first.Keys.Cast<DateTime>()
                    .ToList().OrderBy(k => k);

                var second = all
                    .Where(a => a.AccountID == AccountID) && alertTypes.Contains(a.AlertTypeID))
                    .OrderBy(a => a.CreateDate.Month)
                    .GroupBy(a => a.CreateDate.Month)
                    .ToDictionary(g => firstKeys
                        .First(k => k > g.OrderByDescending(a => a.CreateDate)
                        .FirstOrDefault().CreateDate));

                var combined = first
                    .GroupJoin(
                        second,
                        fk => fk.Key,
                        sk => sk.Key,
                        (d, l) => d.Value
                            .Union(l.SelectMany(i => i.Value).ToArray()))
                    .SelectMany(i => i);

                    result = combined.ToList(); 
            }

            return result;

        }

ジョンのおかげで、私はずっと先に進んでいます。現時点では、次のエラーが発生しています。

シーケンスに一致する要素が含まれていません

この行で(私はかなり確信しています):

.First(k => k > g.OrderByDescending(a => a.CreateDate)

価値のあるものとして、Alertsテーブルのデータは次のようになります。

AlertID AccountID   CreateDate  Timestamp   AlertTypeID    Message
122 5   2008-03-11 20:48:07.983 0x00000000000128FB  9        sdfs
123 1   2008-03-11 20:48:39.957 0x00000000000128FE  8        sdfsd
124 5   2008-03-11 20:48:39.977 0x00000000000128FF  8        sdfs
125 5   2008-03-11 20:48:40.017 0x0000000000012901  8        asdfa
126 1   2008-03-12 22:57:42.160 0x00000000000130B3  4        sfsf
127 5   2008-03-12 22:57:42.337 0x00000000000130B4  4        sdfsd
128 5   2008-03-13 09:42:14.237 0x0000000000013889  4        sdfsd
129 5   2008-03-13 09:42:31.957 0x000000000001388B  4        sdfsd
130 5   2008-03-13 09:42:45.397 0x000000000001388D  5        asdfsdf
131 1   2008-03-16 14:52:17.197 0x0000000000014822  9        asdfsdf
132 1   2008-04-12 15:25:17.330 0x000000000001B582  3        sfasdf
133 5   2008-04-12 15:25:17.700 0x000000000001B583  3        dfsfds
134 6   2008-04-14 08:37:03.273 0x000000000001BD87  3        aasfsd
135 6   2008-04-14 08:37:15.270 0x000000000001BD89  3        fhfsdf
136 6   2008-04-14 08:38:45.120 0x000000000001BD8B  2        ghsdgd
137 6   2008-04-14 08:41:30.407 0x000000000001BD9A  4        fghsdfg
138 6   2008-04-14 08:42:30.800 0x000000000001BD9C  4        gfsdf
139 6   2008-04-14 08:42:43.763 0x000000000001BD9E  5        sdfsdf
140 6   2008-04-14 08:49:25.450 0x000000000001BDAA  9        sdfasdfa
141 6   2008-04-14 08:49:34.237 0x000000000001BDAC  9        sdfasdf
142 1   2008-04-14 08:50:23.380 0x000000000001BDAF  8        sdfhdfhsg
143 6   2008-04-14 08:50:23.567 0x000000000001BDB0  8        dgasdf
144 5   2008-04-14 08:50:23.690 0x000000000001BDB1  8        dgasdf
145 6   2008-04-14 08:50:23.747 0x000000000001BDB2  8         dgasdf
147 1   2008-06-24 14:22:41.183 0x00000000000222E6  14       dgasdf
148 5   2008-06-24 14:22:41.617 0x00000000000222E7  14       dgasdf
149 6   2008-06-24 14:22:41.623 0x00000000000222E8  14       dgasdf
150 1   2008-06-24 20:11:57.757 0x0000000000022AB3  13     dgasdf
151 5   2008-06-24 20:11:57.947 0x0000000000022AB4  13       dgasdf
152 6   2008-06-24 20:11:57.953 0x0000000000022AB5  13       dgasdf
153 1   2008-07-03 18:41:51.067 0x0000000000028888  14       dgasdf
154 5   2008-07-03 18:41:51.230 0x0000000000028889  14        dgasdf
155 6   2008-07-03 18:41:51.237 0x000000000002888A  14        dgasdf
156 1   2008-07-03 18:46:17.873 0x000000000002888D  14       dgasdf
157 5   2008-07-03 18:46:17.937 0x000000000002888E  14       dgasdf
158 6   2008-07-03 18:46:17.940 0x000000000002888F  14        dgasdf
4

1 に答える 1

3

重要なのは、2つのグループを辞書に分割し、最初のリストの日付を辞書のキーとして使用し、2番目のリスト項目の日付の後に最も近いキーを2番目の辞書のキーとして選択することです。

2つの辞書を作成し、それぞれがタイプとサブタイプに共通のキー値を使用するようになったら、を実行して、ソートされたリストで結果を取得できますGroupJoinSelectMany

(*回答は少し異なる以前のバージョンの質問に基づいていることに注意してください。基本的な問題はこの回答ですでに説明され解決されていると思うので、回答を更新するのに時間をかけるつもりはありません)

update 2 First()の呼び出しで発生している問題は、一部のサブアラートアイテムが、例外の原因となる他のアラートアイテムよりも新しい可能性があることです。を使用して最初の辞書に「代理」キーを追加することで対処しました。DateTime::MaxValueその後、最初のリストからサブアラートを除外するのではなく.Distinct()、最終結果で重複を削除するために使用し

linqpadを使用して、この質問をモックアップし、辞書を使用して解決しました。GroupJoin

var all = new []{
    new {date = DateTime.Parse("2012-12-23"), type = "alert", value = 1, accountId = 333 },
    new {date = DateTime.Parse("2012-12-21"), type = "alert", value = 2, accountId = 333 },
    new {date = DateTime.Parse("2012-12-20"), type = "alert", value = 3, accountId = 333 },
    new {date = DateTime.Parse("2012-12-18"), type = "alert", value = 4, accountId = 333 },
    new {date = DateTime.Parse("2012-12-12"), type = "alert", value = 5, accountId = 333 },
    new {date = DateTime.Parse("2012-11-22"), type = "alert", value = 1, accountId = 333 },
    new {date = DateTime.Parse("2012-11-16"), type = "alert", value = 2, accountId = 333 },
    new {date = DateTime.Parse("2012-11-12"), type = "alert", value = 3, accountId = 333 },
    new {date = DateTime.Parse("2012-12-19"), type = "subalert", value = 1, accountId = 333 },
    new {date = DateTime.Parse("2012-12-18"), type = "subalert", value = 2, accountId = 333 },
    new {date = DateTime.Parse("2012-12-04"), type = "subalert", value = 3, accountId = 333 },
    new {date = DateTime.Parse("2012-12-01"), type = "subalert", value = 4, accountId = 333 },
    new {date = DateTime.Parse("2012-11-14"), type = "subalert", value = 1, accountId = 333 },
    new {date = DateTime.Parse("2012-11-08"), type = "subalert", value = 2, accountId = 333 },  
/*add*/ new {date = DateTime.Parse("2012-12-25"), type = "subalert", value = 9, accountId = 333 },  
};

var first = all
    .Where(a=>a.accountId == 333 /* removed && type != "alert" */)
    .OrderByDescending(a=>a.date)
    .GroupBy(a=>a.date.Date)
    .ToDictionary(g=>g.Key);

var firstKeys = first.Keys
    .Cast<DateTime>()
    .Union(new []{DateTime.MaxValue}) /* added this 'surrogate' key */
    .OrderBy(k=>k)
    .ToArray();

var second = all
    .Where(a=>a.accountId == 333 && a.type == "subalert")
    .OrderBy(a=>a.date.Month)
    .GroupBy(a=>a.date.Month)
    .ToDictionary(g=>firstKeys.First(k=>k > g.OrderByDescending(a=>a.date).FirstOrDefault().date));


var combined = first
    .GroupJoin(
        second,
        fk=>fk.Key,
        sk=>sk.Key,
        (d,l)=>d.Value
            .Union(l.SelectMany(i=>i.Value).ToArray()))
    .SelectMany(i=>i)
    .Distinct(); /* Added this to remove duplicates */

combined.Dump();

どちらが得られますか:

更新された結果

于 2012-05-23T20:28:46.600 に答える