4

あるリストから、別のリストには存在しないアイテムを特定する必要があります。2 つのリストは異なるエンティティ (ToDoおよびWorkshopItem) です。Nameが todo リスト アイテムのいずれかに一致する場合、ワークショップ アイテムは todo リストにあると見なします。

以下は私が求めていることですが、再訪するたびに厄介で理解しにくいと感じます。NHibernateQueryOver構文を使用して 2 つのリストを取得し、次に LINQ ステートメントを使用して、要件を満たすワークショップ アイテムのみに絞り込みます (DateDue次の 2 週間で、NameToDo アイテムのリストに存在しません。

var allTodos = Session.QueryOver<ToDo>().List();
var twoWeeksTime = DateTime.Now.AddDays(14);
var workshopItemsDueSoon = Session.QueryOver<WorkshopItem>()
                                  .Where(w => w.DateDue <= twoWeeksTime).List();

var matches = from wsi in workshopItemsDueSoon
              where !(from todo in allTodos
                      select todo.TaskName)
                    .Contains(wsi.Name)
              select wsi;

WorkshopItem理想的には、要件に一致する のリストを返す NHibernate クエリを 1 つだけ使用したいと考えています。

4

3 に答える 3

2

@CSLが提案した回答のLinqバージョンをまとめることができたと思います。次の方向に進んだので、それを受け入れられた回答としてマークします。

var twoWeeksTime = DateTime.Now.AddDays(14);
var subquery = NHibernate.Criterion.QueryOver.Of<ToDo>().Select(t => t.TaskName);
var matchingItems = Session.QueryOver<WorkshopItem>()
                           .Where(w => w.DateDue <= twoWeeksTime && 
                                       w.IsWorkshopItemInProgress == true)
                           .WithSubquery.WhereProperty(x => x.Name).NotIn(subquery)
                           .Future<WorkshopItem>();

私が期待している結果を返し、魔法の文字列に依存しません。私は WithSubquery を完全に理解していないため (そしてインライン化することが良いことかどうか)、躊躇しています。に相当するようです

WHERE WorkshopItem.Name IS NOT IN (subquery)

Futureまた、の代わりに理解できませんList。誰かが助けてくれる人に光を当てるなら。

于 2013-06-05T20:57:15.753 に答える
1

お勧めします

var workshopItemsDueSoon = Session.QueryOver<WorkshopItem>()
                                  .Where(w => w.DateDue <= twoWeeksTime)
var allTodos = Session.QueryOver<ToDo>();

それ以外の

var allTodos = Session.QueryOver<ToDo>().List();
var workshopItemsDueSoon = Session.QueryOver<WorkshopItem>()
                                  .Where(w => w.DateDue <= twoWeeksTime).List();

コレクションが必要になるまで反復されないようにします。

linq 拡張メソッドを使用して、サブクエリをより読みやすく、扱いにくいものにすることが役立つことがわかりました。

例えば:

var matches = from wsi in workshopItemsDueSoon
              where !allTodos.Select(it=>it.TaskName).Contains(wsi.Name)
              select wsi

個人的には、クエリはかなり単純なので、次のようにしたいと思います。

var matches = workshopItemsDueSoon.Where(wsi => !allTodos.Select(it => it.TaskName).Contains(wsi.Name))

後者は私にはあまり冗長ではないようです。

于 2013-06-05T15:00:49.857 に答える