C# の複数のジェネリック リスト<t> - それらを結合しますか?[重複]

StackOverflow https://stackoverflow.com/questions/1497011

  •  19-09-2019
  •  | 
  •  

質問

この質問にはすでに答えがあります:

シナリオ:

Audit の一般的なリストと AuditImage の一般的なリストがあります。これら 2 つのリストはデータベース テーブルから編集されたものです。この結果、1 つの AuditImage に多数の監査が含まれる可能性があります。以下でわかるように、テーブルがマップされるクラスは、データベース内にあるときは外部キー関係「ImageID」によって結合されますが、データがコード内でリストに抽出されると、「物理結合」は存在しません。

DB テーブルがマップされるクラス:

public class AuditImage
{
    public Guid ImageID { get; set; }
    public string LowResUrl { get; set; }
}

public class Audit
{
    public Guid AuditID { get; set; }
    public Guid ImageID { get; set; }
    public DateTime CreatedDate { get; set; }
    public string CreatedBy { get; set; }
    public string Comment { get; set; }
}

問題:

ここで、各リストからデータを抽出し、それを「Audit.ImageID == AuditImage.ImageID」で新しいリストに結合することにより、「Trail」オブジェクトのリストをコンパイルしたいと考えています。

public class Trail
{
    public Guid ImageID { get; set; }
    public DateTime CreatedDate { get; set; }
    public string CreatedBy { get; set; }
    public string Comment { get; set; }
    public string LowResUrl { get; set; }
}

(上記は基本的に、同じ ImageID に基づいて「LowResUrl」フィールドと各監査を組み合わせます。)

質問:

これはどうすればいいでしょうか!?foreach ループと linq を使用して証跡オブジェクトの新しいリストを作成することを考えていましたが、具体的にどのようにすればよいのか全く思いつきません。

ご協力をよろしくお願いいたします。

役に立ちましたか?

解決

あなたが行うことができます。


var trails = from audit in audits
   join image in auditImages on audit.ImageId equals image.ImageId
   select new Trail { ImageID = audit.ImageId, CreatedDate = audit.CreatedDate,
                      CreatedBy = audit.CreatedBy, Comment = audit.Comment,
                      LowResUrl = image.LowResUrl };

他のヒント

リスト上で交差拡張メソッドを試してみてください。 http://msdn.microsoft .COM / EN-US /ライブラリ/ bb910215.aspxする

私はまた、あなたのデザインを見直し、共通インタフェースIAuditまたは類似した何かを導入すべきだと思います。

これは仕事ができる.......

public List<JobImageAudit> CombineForAuditTrail()
        {
            var result = from a in auditList
                         join ai in imageList
                         on a.ImageID equals ai.ImageID
                         //into ait // note grouping        
                         select new JobImageAudit
                         {
                             JobID = a.JobID,
                             ImageID = a.ImageID.Value,
                             CreatedBy = a.CreatedBy,
                             CreatedDate = a.CreatedDate,
                             Comment = a.Comment,
                             LowResUrl = ai.LowResUrl,

                         };
            return result.ToList();
        }

私はおそらく、私は非常にLINQに容易ではないんだという理由だけで、拡張メソッドを使用します:

IEnumerable<Trail> trailList = auditImageList.Join(
  auditList, 
  auditImageItem => auditImageItem.ImageId, 
  auditItem => auditItem.ImageId,
  (auditImageItem, auditItem) =>  new Trail() 
  {  
    LowResUrl = auditImageItem.LowResUrl,
    ImageID = auditImageItem.ImageId, 
    CreatedDate = auditItem.CreatedDate,
    CreatedBy = auditItem.CreatedBy, 
    Comment = auditItem.Comment,
  });

これは単にループ内のオブジェクトを追うために追加のvarクエリから...問題を解決します。

    var query = from auditImage in AuditImageList 
    join audit in AuditList 
on auditImage.ImageID equals audit.ImageID 
select new { ImageID= auditImage.ImageID, CreatedDate = audit.CreatedDate, CreatedBy = audit.CreatedBY, Comment = audit.Comment , LowResUrl = auditImage.LowResUrl }; 

foreach (var trail in query) { //Assign Values to trail object and add to list of trails }

あなたが望むものに依存します:

(それはAuditImageを持っている場合にのみ表示Auditを)

内部結合ます:

var innerJoin = from image in images
                join audit in audits on image.ImageID equals audit.ImageID
                select new { image.ImageID, AuditImageId = audit.ImageID };

(それはAuditImageを持っていない場合でも、表示Auditを)左が加入ます:

var leftJoin = from image in images
               join audit in audits on image.ImageID equals audit.ImageID
               into auditCats
               from auditCat in auditCats.DefaultIfEmpty(new Audit())
               select new { image.ImageID, AuditImageId = auditCat.ImageID };

、少なくとも2つのオプションがあります。

最初はシンプルに参加しますされます:

var trails = Audits.Join(Images, a => a.ImageID, i => i.ImageID, (a, i) =>
    new Trail
    {
        Comment = a.Comment,
        CreatedBy = a.CreatedBy,
        CreatedDate = a.CreatedDate,
        ImageID = a.ImageID,
        LowResUrl = i.LowResUrl
    });

第二には、サブクエリを使用することです。

var trails = Audits.Select(a =>
    new Trail
    {
        Comment = a.Comment,
        CreatedBy = a.CreatedBy,
        CreatedDate = a.CreatedDate,
        ImageID = a.ImageID,
        LowResUrl = Images.Single(i => i.ImageID == a.ImageID).LowResUrl
    });
それは参加するよりも自然に見えるのでIMAGEIDはユニークですが、私個人的には、サブクエリ以上のような場合は、

の両方が正常に動作する必要があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top