少し注意が必要ですが、 linqが動作する新しいインスタンスImageTag
とインスタンスをインスタンス化する機能がある場合は、1つの大きなクエリでそれを行うことができます。Tag
基本的に、外部結合を行う場合はinto
、メソッドでキーワードを使用DefaultIfEmpty(...)
して「外部結合ギャップ」を処理する必要があります(たとえば、通常のSQL左外部結合で結合キーの右側がnullの場合)。 。
var images=db.Imagesのimgから
img.idImageのdb.ImageTagsにimgTagsを結合すると、imgTags.idImageと等しくなります
outerImageRefに
externalImageRef.DefaultIfEmpty(new ImageTag(){idImage = img.idImage、idTag = -1})のouterIRから
imgTags.idTagのdb.Tagsにtを結合するとt.idTagと等しくなります
outerRefTagsに
externalRefTags.DefaultIfEmpty(new Tag(){idTag = -1、TagName = "untagged"})のouterRTから
imgをouterRT.TagNameでaGroupにグループ化します
新しい{を選択します
GroupName = aGroup.Key、
アイテム=aGroupのxから
新しいImageFragment()を選択します{
ImageID = x.idImage、
ScanDate = x.ScanTime
}
};
正確な環境がないため、上記のコンパイルがうまくいけば、独自のデータ型を使用してソリューションを構築し、それを質問の説明に変換しました。基本的に重要な部分は、従来のSQLの意味で考えている場合に、メモリ内にある大規模に結合されたテーブルに余分な「行」を追加するのに本質的に役立つ余分な行ですinto
。DefaultIfEmpty
ただし、linqエンティティのメモリ内インスタンス化を必要としないより読みやすいソリューションがあります(これを自分の環境に変換する必要があります)。
//この最初のクエリは、TagNameとImageIdを持つ匿名タイプのコレクションを返します。
//基本的にImageTagsx-refテーブルとTagsを結合することからの関係
//各行はタグと画像IDです(Robert HarveyがQへのコメントで述べたように)
vartagNamesWithImageIds=タグ内のタグから
tag.IdTagのImageTagsでreferを結合します。refer.IdTagと同じです。
新しい{を選択します
TagName = tag.Name、
ImageId = refer.IdImage
};
//これで、画像を上記の関係に外部結合することでソリューションを取得できます
//そして「外部結合ギャップ」を再び「タグなし」の匿名タイプで埋めます
//次に、それをもう一度Imagesテーブルに結合して、グループ化と投影を取得します。
var images = from img in Images
img.IdImageのtagNamesWithImageIdsのtをt.ImageIdに等しくします
アウタージョインに
からouterJoin.DefaultIfEmpty(new {TagName = "untagged"、ImageId = img.IdImage})
o.ImageIdの画像でimg2を結合するとimg2.IdImageと等しくなります
img2をo.TagNameでaGroupにグループ化します
新しい{を選択します
TagName = aGroup.Key、
Images = aGroup.Select(i => i.Data).ToList()//これをコードのロジックに置き換える必要があります。ワークスペースには、はるかに単純なデータ型がありました。
};
それが理にかなっていることを願っています。もちろん、いつでもアプリケーションをデフォルトで「タグなし」ですべてにタグ付けするように設定するか、もっと単純なLINQクエリを実行して、ImageTagテーブルに存在しない画像IDのリストを作成し、次にユニオンなどを作成することができます。