C # Multiple common list <t> - Combine them?

Scenario:

I have a generic list of audits and a generic list of AuditImages. These two lists were compiled from database tables. As a result, ONE AuditImage can have many audits. As you will see below, the classes to which the tables are bound are bound by the foreign key relationship "ImageID" when they are in the database, however, once the data is fetched into the lists in the code, there is no "PHYSICAL JOIN".

Classes that appear in DB tables:

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; }
}

      

Problem:

Now I want to compile a list of "Trail" objects by extracting data from each list and concatenating it in "Audit.ImageID == AuditImage.ImageID" into a new list.

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; }
}

      

(The above essentially combines the "LowResUrl" field with each audit based on the ImageID, which is the same.)

Question:

How do I do this ?? I was thinking about using foreach and linq loops to create a new list of trail objects, but I can't really think of exactly how I would do this ?!

Help would be greatly appreciated.

+2


source to share


7 replies


you could do




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 };

      

+4


source


Try the Intersect extension method on List: http://msdn.microsoft.com/en-us/library/bb910215.aspx



I also think you should consider your design and introduce a generic IAudit interface or something similar.

0


source


It might work ........

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();
        }

      

0


source


I would probably use extension methods, just because I'm not very easy on 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,
  });

      

0


source


This will solve the problem .. from the var request just add the trail objects to the loop

    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 }

      

0


source


Depending on what you want:

Inner join (only display AuditImage

if it has Audit

):

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

      

Left join (display AuditImage

even if it doesn't have 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 };

      

0


source


There are at least two options.

First, a simple join is done:

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
    });

      

Second, you need to use a subquery:

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
    });

      

Both should work fine as long as the ImageID is unique, but I personally like the extra query because it looks more natural than concatenation.

0


source







All Articles