1

非常に単純なテーブルに対してクエリを実行しようとしていますが、結果が得られません。テーブルには、次の列を持つアクション ログが含まれています。

  • ID
  • ActionTypeID (作成、編集、または削除)
  • EntryID (作成/編集/削除されたエントリの ID)
  • TableName (アクションがコミットされた場所)
  • コントロール名
  • Person (アクションをコミットした人。nt-user with department)
  • 日にち

私が取得したかったのは、すべての EntryID のリストであり、ActionTypeID == 1 で、Person (部門) が文字列の動的リストの 1 つで終わります。問題は、アクション ログ内の 1 つの EntryID に対する最初のアクションのみをチェックして、これらの部門の 1 つと一致する必要があることです。

私はこれがかなり奇妙に聞こえることを知っています。これは、私の英語力の低さと、以前の同僚のデータベース設計の障害が原因である可能性があります。どっちが悪いのかわからない。

私が望んでいた結果を得るための私の試みはこれです:

var predicate = PredicateBuilder.False<ActionLog>();
var pOuter = PredicateBuilder.True<ActionLog>();

pOuter = pOuter.And(h => h.TableName.ToUpper() == "Contact".ToUpper());
pOuter = pOuter.And(h => h.ActionType.ID == 1);

foreach (var dep in b.DepartmentList)
{
    predicate = predicate.Or(x => x.Person.EndsWith("/" + dep.Value));
}

pOuter = pOuter.And(predicate.Expand());

mContactIDs = (from h in db.ActionLog
orderby h.Date
select h).AsExpandable().Where(pOuter).Select(x => x.EntryID).Distinct().ToList();

しかし、これにより、「人」が選択した部門で終わるすべてのエントリが返されます。この EntryID で最初のエントリを確認したいだけです。

私が混乱したドイツ語から奇妙な英語に翻訳しようとしていることを誰かが理解してくれることを願っています.

あ、ちなみに.Net 3.5です

編集 正しい説明を見つけるのに問題があると思います-ダミーデータで試してみます。

ID | ActionTypeID | EntryID | TableName  | ControlName | Person             | Date
----------------------------------------------------------------------------------------
1  | 1            | 3       | 'Contacts' | NULL        | 'xxxx/department1' | 04/11/2012
2  | 1            | 3       | 'Contacts' | NULL        | 'yyyy/department2' | 04/11/2012
3  | 1            | 5       | 'Contacts' | NULL        | 'yyyy/department2' | 04/13/2012
4  | 1            | 14      | 'Contacts' | NULL        | 'zzzz/department1' | 04/16/2012

私の例では、「'/department2' で終わる人は、新しい EntryID の最初の出現を作成しました」、「TableName == 'Contacts'」、および「ActionTypeID == 1」のログ エントリを検索します。受信したい結果は (EntryID のみ) 5 になります。これは、部門 2 のユーザーが最初に入力された唯一のエントリです。ActionTypeID 1 でこの EntryID を挿入します。私はこれがばかげていることを知っています。こんな風にはならなかったでしょうが、今は対処しなければなりません。クエリする部門の数が動的でない場合は、次のスニペットを使用します。

IQueryable<ActionLog> log = db.ActionLog;
mContactIDs = (from k in db.Contacts
    where (from h in log
        where h.TableName == "Contacts"
        && h.EntryID == k.ID
        && h.ActionType.ID == 1
        orderby h.Date
        select h).FirstOrDefault().Person.EndsWith("/" + b.Department)
    select k.ID).ToList();

しかし、これらの動的な部門を愚かな設計 (および 1 つのエントリに対して複数の ActionTypeID 1 (作成) を使用する方法。アプリケーションがこれを保存する理由もわかりません) を接続する方法がわかりません。

ありがとう、ベン。

4

2 に答える 2

0

dep.Value問題は、 foreach ループ内のキャプチャされた変数値(つまり)だと思います。変数のコピーを作成し、それを式で使用します。問題はここで説明されています。

foreach (var dep in b.DepartmentList)
{
    var depValue = dep.Value;
    predicate = predicate.Or(x => x.Person.EndsWith("/" + depValue));
}
于 2012-04-17T04:01:11.527 に答える
0

代わりに Entity SQL を使用することにしました。

        List<int> mContactIDs = new List<int>();
        using (var db = new Entities())
        {
            string queryString = @"
                                SELECT  
                                    VALUE H.EntryID
                                FROM    
                                    Entities.ActionLog AS H
                                WHERE 
                                    H.ID IN (
                                        SELECT VALUE TOP (1) Hi.ID
                                        FROM Entities.ActionLog AS Hi
                                        WHERE Hi.ActionType.ID = 1
                                        AND Hi.TableName = 'Kontakt'
                                        AND Hi.EntryID = H.EntryID
                                        ORDER BY Hi.Date    
                                    )
                                {0}
                                GROUP BY H.EntryID";

            List<string> lDepartments = new List<string>();
            foreach (var dep in b.DepartmentList)
            {
                lDepartments.Add(string.Format(" H.Person LIKE '%{0}' ", dep.Value));
            }

            string sDepartmentQuery = string.Empty;
            if (lDepartments.Count > 0)
            {
                sDepartmentQuery = string.Format(" AND ({0}) ", string.Join(" OR ", lDepartments.ToArray()));
            }

            var result = db.CreateQuery<int>(string.Format(queryString, sDepartmentQuery));
            if (result != null && result.Count() > 0)
            {
                mContactIDs = result.ToList();
            }
        }
于 2012-04-23T13:19:26.437 に答える